使用webpack4.x定制本身的前端开发环境

一,最基础的环境

1,初始化环境

yarn init (npm init)
复制代码

2,安装webpack webpack-cli

说明webpack-cli 在4.0版本已经脱离了webpack 须要单独按照,我的建议最好把按照包安装在项目环境里,这样能够确保整个项目用的版本同样
复制代码
yarn add webpack

      yarn add webpack-cli
复制代码

3,在package.json 添加script

"scripts": { "build": "webpack --mode production" }css

4,咱们在项目目录下添加一个文件src/index.js

(这是webpack默认的入口文件)html

5,执行命令

yarn run dev
复制代码

6, webpack.config.js的基本内容

const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: [path.resolve(__dirname, 'src')]
            },
        ],
    },

    // 代码模块路径解析的配置
    resolve: {
        modules: [
            "node_modules",
            path.resolve(__dirname, 'src')
        ],

        extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
    },

    plugins: [
        new UglifyPlugin(),
        // 使用 uglifyjs-webpack-plugin 来压缩 JS 代码
        // 若是你留意了咱们一开始直接使用 webpack 构建的结果,你会发现默认已经使用了 JS 代码压缩的插件
        // 这其实也是咱们命令中的 --mode production 的效果,后续的小节会介绍 webpack 的 mode 参数
    ],
}
复制代码

基本解析:node

注意:loader 和plugins都须要单独安装, 安装到 devDependencies 由于这些插件都只是构建代码时候有用webpack

二,经常使用plugins

1,UglifyPlugin

这个用来进行js代码压缩es6

yarn add uglifyjs-webpack-plugin --dev
复制代码

2,html-webpack-plugin

这个用户把打包好的js文件动态插入到index.html 默认入口文件为根目录下index.html 出口文件默认为dist目录下index.tmlweb

yarn add uglifyjs-webpack-plugin --dev
复制代码

也容许本身定义express

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // 配置输出文件名和路径
      template: 'assets/index.html', // 配置文件模板
    }),
  ],
}
复制代码

⚠️为何须要这个插件?为何要动态插入? 主要是由于咱们进行打包 为了防止浏览器缓存,每每须要给打包出来到文件添加[hash]。 因此就须要动态插入npm

3,extract-text-webpack-plugin@next

若是只用 css-loader & style-loader来转换代码,css会编程js代码动态插入到html中 若是想把css单独成一个文件,就须要使用这个plugin编程

4,DefinePlugin

DefinePlugin 是 webpack 内置的插件,可使用 webpack.DefinePlugin 直接获取。json

这个插件用于建立一些在编译时能够配置的全局常量,这些常量的值咱们能够在 webpack 的配置中去指定,例如:

5,copy-webpack-plugin

咱们通常会把开发的全部源码和资源文件放在 src/ 目录下,构建的时候产出一个 build/ 目录,一般会直接拿 build 中的全部文件来发布。有些文件没通过 webpack 处理,可是咱们但愿它们也能出如今 build 目录下,这时就可使用 CopyWebpackPlugin 来处理了。

通常开发时,会在根目录下static目录直接拷贝过去

new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: 'static',
    ignore: ['.*']
  }
])
yarn add copy-webpack-plugin -D
复制代码

6,ProvidePlugin

ProvidePlugin 也是一个 webpack 内置的插件,咱们能够直接使用 webpack.ProvidePlugin 来获取。

该组件用于引用某些模块做为应用运行时的变量,从而没必要每次都用 require 或者 import,其用法相对简单:

new webpack.ProvidePlugin({
  identifier: 'module',
  // ...
})

// 或者
new webpack.ProvidePlugin({
  identifier: ['module', 'property'], // 即引用 module 下的 property,相似 import { property } from 'module'
  // ...
})
复制代码

在你的代码中,当 identifier 被看成未赋值的变量时,module 就会被自动加载了,而 identifier 这个变量即 module 对外暴露的内容。

注意,若是是 ES 的 default export,那么你须要指定模块的 default 属性:identifier: ['module', 'default'],。

7,IgnorePlugin

IgnorePlugin 和 ProvidePlugin 同样,也是一个 webpack 内置的插件,能够直接使用 webpack.IgnorePlugin 来获取。

这个插件用于忽略某些特定的模块,让 webpack 不把这些指定的模块打包进去。例如咱们使用 moment.js,直接引用后,里边有大量的 i18n 的代码,致使最后打包出来的文件比较大,而实际场景并不须要这些 i18n 的代码,这时咱们可使用 IgnorePlugin 来忽略掉这些代码文件,配置以下

module.exports = {
  // ...
  plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
}
复制代码

8,optimize-css-assets-webpack-plugin

css 代码压缩

const optimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [
    new optimizeCss()
]


yarn add  optimize-css-assets-webpack-plugin -D
复制代码

三,经常使用loaders

1,babel-loader

这个loader能够把es6 + 代码转换为es5到代码。由于浏览器对于es6的代码兼容很差,可是es6不少新语法对于咱们开发工做提高很高。因此须要把 es6代码作转换。

yarn add babel-loader  @babel/core --dev
复制代码

2,css-loader & style-loader

css-loader 负责解析 CSS 代码,主要是为了处理 CSS 中的依赖,例如 @import 和 url() 等引用外部文件的声明; style-loader 会将 css-loader 解析的结果转变成 JS 代码,运行时动态插入 style 标签来让 CSS 代码生效。

{
    test: /\.css/,
    include: [
        path.resolve(__dirname, 'src'),
    ],
    use: [
        'style-loader',
        'css-loader',
    ],
}
复制代码

注意:['style-loader','css-loader']这里的配置是有顺序的,但规则应用顺序是从右到左的。也就是先 css-loader,再style-loader

yarn add css-loader style-loader --dev

复制代码

segmentfault.com/a/119000001…

3,less-loader

css 预编译器

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.less$/,
        // 由于这个插件须要干涉模块转换的内容,因此须要使用它对应的 loader
        use: ExtractTextPlugin.extract({ 
          fallback: 'style-loader',
          use: [
            'css-loader', 
            'less-loader',
          ],
        }), 
      },
    ],
  },
  // ...
}

yarn add less less-loader -D
复制代码

4,file-loader & url-loader & image-webpack-loader

file-loader 能够用于处理图片文件

{
    test: /\.(png|jpg|gif)$/,
    use: [
        {
            loader: 'file-loader',
            options: {},
        },
    ],
}

yarn add file-loader -D
复制代码

简答地说,url-loader封装了file-loader。url-loader不依赖于file-loader,即便用url-loader时,只须要安装url-loader便可,不须要安装file-loader,由于url-loader内置了file-loader。

经过上面的介绍,咱们能够看到,url-loader工做分两种状况:

1)文件大小小于limit参数,url-loader将会把文件转为DataURL;

2)文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。所以咱们只须要安装url-loader便可。

url-loader

{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 10000,
    name: utils.assetsPath('img/[name].[hash:7].[ext]')
  }
},
{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 10000,
    name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  }
}

yarn add url-loader -D
复制代码

image-webpack-loader能够用来作图片压缩

{
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: { // 压缩 jpeg 的配置
                progressive: true,
                quality: 65
              },
              optipng: { // 使用 imagemin-optipng 压缩 png,enable: false 为关闭
                enabled: false,
              },
              pngquant: { // 使用 imagemin-pngquant 压缩 png
                quality: '65-90',
                speed: 4
              },
              gifsicle: { // 压缩 gif 的配置
                interlaced: false,
              },
              webp: { // 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式
                quality: 75
              },
          }
yarn add image-webpack-loader

复制代码

5,NamedModulesPlugin(), && HotModuleReplacementPlugin()

热模块替换相关

plugins: [ // ... new webpack.NamedModulesPlugin(), // 用于启动 HMR 时能够显示模块的相对路径 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件 ],

四, 本地服务器 webpack-dev-server & webpack-dev-middleware

1, webpack-dev-server使用

添加script

"start": "webpack-dev-server --mode development"
复制代码

new webpack.NamedModulesPlugin(), // 用于启动 HMR 时能够显示模块的相对路径 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件

webpack-dev-server当更多配置查看https://webpack.docschina.org/configuration/dev-server/

yarn add webpack-dev-server -D

2 ,webpack-dev-middleware使用

咱们也可使用webpack-dev-middleware 来启动静态服务器 使用以下 首先安装 webpack-dev-middleware 依赖:

npm install webpack-dev-middleware --save-dev
复制代码

接着建立一个 Node.js 服务的脚本文件,如 app.js:

const webpack = require('webpack')
const middleware = require('webpack-dev-middleware')
const webpackOptions = require('./webpack.config.js') // webpack
复制代码

配置文件的路径

// 本地的开发环境默认就是使用 development mode

webpackOptions.mode = 'development'
const compiler = webpack(webpackOptions)
const express = require('express')
const app = express()

app.use(middleware(compiler, {
  // webpack-dev-middleware 的配置选项
}))

// 其余 Web 服务中间件
// app.use(...)

app.listen(3000, () => console.log('Example app listening on port 3000!'))
复制代码

添加script

"start": "node app.js"
复制代码

五,配置拆分

webpack.base.js:基础部分,即多个文件中共享的配置 webpack.development.js:开发环境使用的配置 webpack.production.js:生产环境使用的配置 所以,只要有一个工具能比较智能地合并多个配置对象,咱们就能够很轻松地拆分 webpack 配置,而后经过判断环境变量,使用工具将对应环境的多个配置对象整合后提供给 webpack 使用。这个工具就是 webpack-merge。

相关文章
相关标签/搜索