Skip to content

Webpack 配置文件

webpack 的配置文件主要是webpack.config.js

如果没有此配置文件,它默认会使用自己的默认配置。

JS
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js',
  },
};

entry 和 output

entry选项是用来配置入口文件的,它可以是字符串、数组或者对象类型。webpack默认只支持jsjson文件作为入口文件,因此如果引入其他类型文件会保存。

output选项是设置输出配置,该选项必须是对象类型,不能是其它类型格式。在output对象中,必填的两个选项就是导出路径path和导出bundle文件名称filename。其中path选项必须为绝对路径。

entryoutput的配置,对于不同的应用场景的配置也会有所不同。

单入口单输出

我们最普遍的就是单个入口文件,然后打包成单个bundle文件。这种应用场景下,entry可以使用字符串的形式,则跟默认配置文件类似:

javascript
entry: './src/index.js';

多入口单输出

当我们的项目需要有多个入口文件,但只需要一个输出bundle的时候,这时候entry可以使用数组的形式:

javascript
entry: ['./src/index_1.js', './src/index_2.js'];

注意:此时其实只有一个 chunk

多入口多输出

当我们的项目同时多个入口文件,并且它们需要单独打包,也就是意味着会有多个bundle文件输出,此时我们的entry需要使用对象形式,并且对象key对应的对应chunk的名称。

javascript
entry: {
  index: "./src/index.js",  // chunkName为index
  main: "./src/main.js"     // chunkName为main
}

此时,我们的output.filename也不能写死了,这时候webpack提供了一个占位符[name]给我们使用,它会自动替换为对应的chunkName

javascript
output: {
   path: path.resolve(__dirname, 'dist'),
   filename: '[name].js'  // [name]占位符会自动替换为chunkName
},

根据上面的配置,最后会打包出index.jsmain.js

补充

在单入口单输出的应用场景下,entry也可以使用对象的形式,从而来自定义chunkName,然后output.filename也使用[name]占位符来自动匹配。当然也可以使用数组,但是不太大必要。

entry使用数组或字符串的时候,chunkName默认为main,因此如果output.filename使用[name]占位符的时候,会自动替换为main

mode

在前面的打包测试的时候,命令行都会报一个警告:

shell
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.

这是因为webpack需要我们配置mode选项。

wepack 给我们提供了三个选项,即nonedevelopmentproduction,而默认就是production

三者的区别呢,在于webpack自带的代码压缩和优化插件使用。

  • none:不使用任何默认优化选项;
  • development:指的是开发环境,会默认开启一些有利于开发调试的选项,比如NamedModulesPluginNamedChunksPlugin,分别是给modulechunk命名的,而默认是一个数组,对应的chunkName也只是下标,不利于开发调试;
  • production:指的是生产环境,则会开启代码压缩和代码性能优化的插件,从而打包出来的文件也相对nonedevelopment小很多。

当我们设置 mode 之后,我们可以在process.env.NODE_ENV获取到当前的环境

因此我们可以在配置文件上文件上配置mode

javascript
const path = require('path');

module.exports = {
  mode: 'development', // 开发模式
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
};

webpack也给我们提供了另一种方式,就是在命令行中配置,也就是加上--mode

javascript
// package.json
"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}

devtool

聊完mode后,说到开发调试,不难想起的就是sourceMap。而我们可以在配置文件中,使用devtool开启它。

javascript
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
  // 开启source-map
  devtool: 'source-map',
};

打包后,你的dist中就会多了一个main.js.map文件。

当然,官方不止提供这么一个选项,具体的可以去官网看看,这里就说其他几个比较常用的选项。

  • none:不会生成sourceMap
  • eval:每个模块都会使用eval()执行,不建议生成环境中使用;
  • cheap-source-map:生成sourceMap,但是没有列映射,则只会提醒是在代码的第几行,不会提示到第几列;
  • inline-source-map:会生成sourceMap,但不会生成map文件,而是将sourceMap放在打包文件中。

module

前面我们有提到过,就是webpack的入口文件只能接收JavaScript文件和JSON文件。

但我们通常项目还会有其他类型的文件,比如htmlcss、图片、字体等等,这时候我们就需要用到第三方loader来帮助webpack来解析这些文件。理论上只要有相应的loader,就可以处理任何类型的文件。

webpack官网其实提供了很多loader,已经能满足我们日常使用,当然我们也可以去github找找别人写的loader或者自己手写loader来使用。

而对于loader的配置,是写着module选项里面的。module选项是一个对象,它里面有一个rules属性,是一个数组,在里面我们可以配置多个匹配规则。

而匹配规则是一个对象,会有test属性和use属性,test属性一般是正则表达式,用来识别文件类型,而use属性是一个数组,里面用来存放对该文件类型使用的loader

javascript
module: {
  rules: [
    {
      test: /\.css$/, // 识别css文件
      use: ['style-loader', 'css-loader'], // 对css文件使用的三个loader
    },
  ];
}

对于use数组的顺序是有要求的,webpack会根据自后向前的规则去执行loader。也就是说,上面的例子webpack会先执行css-loader,再执行style-loader

其次,当我们需要对对应loader提供配置的时候,我们可以选用对象写法:

javascript
module: {
    rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            {
              	// loader名称
              	loader: 'css-loader',
              	// loader选项
              	options: {
                  	...
                }
            }
          ]
        }
    ]
}

在后面我们根据实际应用场景再讲讲module的使用。

plugins

webpack还提供了一个plugins选项,让我们可以使用一些第三方插件,因此我们可以使用第三方插件来实现打包优化、资源管理、注入环境变量等任务。

同样的,webpack官方也提供了很多plugin

plugins选项是一个数组,里面可以放入多个plugin插件。

javascript
plugins: [new htmlWebpackPlugin(), new CleanWebpackPlugin(), new miniCssExtractPlugin(), new TxtWebpackPlugin()];

而对于plugins数组对排序位置是没有要求,因为在plugin的实现中,webpack会通过打包过程的生命周期钩子,因此在插件逻辑中就已经设置好需要在哪个生命周期执行哪些任务。

Released under the MIT License.