最近不是在写hw么,所以就撸了一遍webpack的文档,按说这事情一年前就该做了。
不过前端的工程搭建不知道为啥这么复杂。
配置文件结构
不管create-react-app、vue-cli这些工具怎么封装,最后webpack肯定是运行一个配置文件,这个文件可以是js也可以是json(还可以是别的),个人感觉应该是json格式用的比较多吧。一般配置内容可以分成这么几个部分:
- 入口(entry)
- 输出(output)
- 模块(module)
- resolve
- 加载器(loader)
- 插件(plugin)
- 开发用服务器、devtool、watch
- 还有一些别的,比如external、performance等
输出
output: {
path: path.resolve(__dirname, "dist"), // 输出路径
filename: "[name]_[hash].js",
chunkFilename: "[name]_[hash].chunk.js",
publicPath: "/assets/", // 存放图片、文件等资源的文件夹
sourceMapFilename: "[file].map" // sourcemap文件名
}
模块
module: {
noParse: [ // 不解析的模块
/special-library\.js$/
],
rules: [
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "src") // 尽量用这个而不是用exclude
],
exclude: [
path.resolve(__dirname, "app/demo-files") // 尽量用include
],
loader: "babel-loader", // loader的执行顺序和写的顺序是相反的
options: {
presets: ["es2015"] // loader 的可选项
},
},
{
test: /\.html$/,
include: [
path.resolve(__dirname, "src")
],
use: [
"htmllint-loader", // 应用多个 loader 和选项
{
loader: "html-loader", // 可以是字符串,也可以是对象
options: {
/* ... */
}
}
]
}
],
}
resolve
resolve: {
alias: {
Templates: path.resolve(__dirname, "src/templates/") // 引用的时候可以直接 import * from 'Templates/xxx',而不用 '../../templates/xxx'
},
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"] // import时可以不用写这些后缀名
}
其他
performance: {
hints: "error", // 打包出来的文件大小警告
maxEntrypointSize: 500000, // 入口文件大小
assetFilter: function(assetFilename) { // 过滤资源文件类型
return assetFilename.endsWith(".css") || assetFilename.endsWith(".js");
}
},
optimization: {
minimize: true,
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
chunks: "all",
name: 'vendor' // 给输出的chunk重新命名
}
}
}
},
mode: "development", // 还可以是production,启用的优化效果不同
devtool: "cheap-module-source-map", // sourcemap功能,
watch: true, // 启用文件观察模式,开发模式下才需要
watchOptions: {
aggregateTimeout: 1000, // 将多个更改聚合到单个构建
poll: 500, // 文件轮询间隔单位 ms
},
devServer: { // 不应该和上面的watch一起用,不要和SourceMapDevToolPlugin、EvalSourceMapDevToolPlugin一起使用
proxy: {
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // 静态文件的路径
compress: true, // 压缩
},
开发服务器还可以用webpack-dev-middleware,自由度更高,配置devServer选项时表示用的是webpack-dev-server,使用watch表示不用开发服务器,只是监听文件变更
webpack-bundle-analyzer可以分析各个包的大小,并直观显示
搭建基本的工程用上面这些配置就够了,其中有些互斥的插件、配置、加载器什么的,最好能看一遍文档,一些高级用法、优化什么的就要用到插件了
比较常用的一些插件:
HtmlWebpackPlugin:生成html文件和js、css标签
CleanWebpackPlugin:清理文件
WebpackManifestPlugin:生成文件映射
SourceMapDevToolPlugin:生成sourcemap
ClosureCompilerPlugin:压缩,和UglifyJSPlugin类似
DefinePlugin:定义环境变量
ExtractTextWebpackPlugin:为样式单独抽取文件,而不写在js bundle里,提高加载速度,4中已弃用,使用MiniCssExtractPlugin
CommonsChunkPlugin:提取公共部分,4中已弃用,使用SplitChunksPlugin
HashedModuleIdsPlugin:根据模块的相对路径生成hash作为模块id
DllPlugin