webpack学习笔记

入口和出口

  • 单个入口
    1
    2
    3
    4
    5
    module.exports = {
    entry: {
    main: './index.js',
    },
    };
  • 多个入口(数组)
    1
    2
    3
    4
    5
    6
    module.exports = {
    entry: ['./index1.js', './index2.js'],
    output: {
    filename: './dist/bundle.js',
    },
    };
  • 多个入口(对象)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // webpack.config.js
    module.exports = {
    entry: {
    main: './src/app.js',
    vendor: './src/vendor.js'
    }
    };

    // webpack.prod.js
    module.exports = {
    output: {
    filename: '[name].[contenthash].bundle.js',
    },
    };

    // webpack.dev.js
    module.exports = {
    output: {
    filename: '[name].bundle.js',
    },
    };

入口配置参数:

  • dependOn:当前入口所依赖的入口。它们必须在该入口被加载前被加载。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
};

module.exports = {
output: {
path: '/home/proj/cdn/assets/[fullhash]',
publicPath: 'https://cdn.xxx.com/assets/[fullhash]/'
}
};

loader

loader从右到左执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
},
{ loader: 'sass-loader' }
]
}
]
}
};

内联方式

1
import Styles from '!style-loader!css-loader?modules!./style.css';

plugin

webpack插件是一个具有apply方法的JavaScript对象。apply方法会被webpack compiler调用,并且在整个编译生命周期都可以访问compiler对象。

1
2
3
4
5
6
7
8
9
10
11
12
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new webpack.ProgressPlugin()
]
};

ProgressPlugin用于自定义编译过程中的进度报告,HtmlWebpackPlugin将生成一个HTML文件,并在其中使用script引入一个名为my-first-webpack.bundle.jsJS文件。

模块解析

resolver是一个帮助寻找模块绝对路径的库。

webpack中的解析规则

使用enhanced-resolvewebpack能解析三种文件路径:

  • 绝对路径

    1
    2
    import '/home/me/file';
    import 'C:\\Users\\me\\file';
  • 相对路径

    1
    2
    import '../src/file1';
    import './file2';

    使用importrequire的资源文件所处的目录,被认为是上下文目录。在import/require中给定的相对路径,会拼接此上下文路径,来生成模块的绝对路径。

  • 模块路径

    1
    2
    import 'module';
    import 'module/lib/file';

    resolve.modules中指定的所有目录中检索模块。通过配置别名的方式来替换初始模块路径。

  • 如果package中包含package.json文件,在resolve.exportsFields配置选项中指定的字段会被一次查找。

根据规则解析路径,resolver将会检查路径是指向文件还是文件夹。

如果路径指向文件:

  • 文件具有扩展名,则直接将文件打包。
  • 否则,使用resolve.extensions选项作为文件扩展名来解析。

如果路径指向一个文件夹:

  • 如果文件夹中包含package.json文件,则会根据resolve.mainFields配置中的字段顺序查找,并根据package.json中的符合配置要求的第一个字段来确定文件路径。
  • 如果不存在package.json文件或resolve.mainFields没有返回有效路径,则会根据resolve.mainFields配置选项中指定的文件名顺序查找,看是否能在import/require的目录下匹配到一个存在的文件名。
  • 然后使用resolve.extensions选项,以类似的方式解析文件扩展名。

缓存

每次文件系统访问文件都会被缓存,以便于更快触发对同一文件的多个并行或串行请求。在watch模式下,只有修改过的文件会被从缓存中移除。如果关闭watch模块,则会在每次编译前清理缓存。