1. entry(入口起点)
【用法】entry: string | [string]
1.1 单一入口
entry 属性单入口语法:
module.exports = {
entry: {
main: './src/main.js'
}
//...
};
简写语法:
module.exports = {
entry: './src/main.js'
//...
};
也可以将一个文件路径数组传递给entry属性
module.exports = {
entry: ['./src/main_1.js', './src/main_2.js']
//...
};
【优点】当通过一个入口为应用程序快速配置webpack时,单一入口的语法是很好的选择。
【缺点】使用这种语法方式它的扩展性、配置灵活性不大。
1.2 对象语法
【用法】entry: { string | [string] } | {}
entry 属性对象语法:
module.exports = {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js'
}
//...
};
对象语法会比较繁琐。然而,这是应用程序中定义入口的最可扩展的方式。
描述入口的对象,属性:
dependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
filename: 指定要输出的文件名称。
import: 启动时需加载的模块。
library: 指定 library 选项,为当前 entry 构建一个 library。
runtime: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。
publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。
“webpack 配置的可扩展” 是指,这些配置可以重复使用,并且可以与其他配置组合使用。这是一种流行的技术,用于将关注点从环境(environment)、构建目标(build target)、运行时(runtime)中分离。然后使用专门的工具(如 webpack-merge)将它们合并起来。
1.3 常见场景
1.3.1 分离 app(应用程序) 和 vendor(第三方库) 入口
module.exports = {
entry: {
main: './src/app.js',
vendor: './src/vendor.js'
}
//...
};
以上代码告诉 webpack 我们想要配置 2 个单独的入口点。
这样你就可以在 vendor.js 中存入未做修改的必要 library 或文件(例如 Bootstrap, jQuery, 图片等),然后将它们打包在一起成为单独的 chunk。内容哈希保持不变,这使浏览器可以独立地缓存它们,从而减少了加载时间。
1.3.1 多页面应用程序
module.exports = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
//...
};
以上告诉 webpack 需要三个独立分离的依赖图。
在多页面应用程序中,server 会拉取一个新的 HTML 文档给你的客户端。页面重新加载此新文档,并且资源被重新下载。然而,这给了我们特殊的机会去做很多事,例如使用 optimization.splitChunks 为页面间共享的应用程序代码创建 bundle。由于入口起点数量的增多,多页应用能够复用多个入口起点之间的大量代码/模块,从而可以极大地从这些技术中受益。
2. output(输出)
可以通过配置 output 选项,告知 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个 entry 起点,但只能指定一个 output 配置。
2.1 用法
在 webpack 配置中,output 属性的最低要求是,将它的值设置为一个对象,然后为将输出文件的文件名配置为一个 output.filename:
module.exports = {
//...
output: {
filename: 'bundle.js'
}
};
此配置将一个单独的 bundle.js 文件输出到 dist 目录中。对于单一入口起点,filename 会是一个静态名称。
2.1.1 使用入口名称
module.exports = {
//...
output: {
filename: '[name].bundle.js'
}
};
2.1.2 使用内部 chunk id
module.exports = {
//...
output: {
filename: '[id].bundle.js'
}
};
2.1.3 使用由生成的内容产生的 hash
module.exports = {
//...
output: {
filename: '[contenthash].bundle.js'
}
};
2.1.4 结合多个替换组合使用
module.exports = {
//...
output: {
filename: '[name].[contenthash].bundle.js'
}
};
2.1.5 使用函数返回 filename
module.exports = {
//...
output: {
filename: (pathData) => {
return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
}
}
};
2.2 多个入口起点
如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用 [占位符substitutions 来确保每个文件具有唯一的名称。
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist' //path:output 目录对应一个绝对路径。
}
};
写入到dist目录:./dist/app.js, ./dist/search.js
2.3 高级进阶
对资源使用 CDN 和 hash 的复杂示例:
module.exports = {
//...
output: {
path: '/home/proj/cdn/assets/[fullhash]',
publicPath: 'https://cdn.example.com/assets/[fullhash]/'
}
};
如果在编译时,不知道最终输出文件的 publicPath 是什么地址,则可以将其留空,并且在运行时通过入口起点文件中的 webpack_public_path 动态设置。
__webpack_public_path__ = myRuntimePublicPath;
3. loader(加载器)
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 "load(加载)" 模块时预处理文件
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
module.rules允许你在 webpack 配置中指定多个 loader。
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
// [style-loader](/loaders/style-loader)
{ loader: 'style-loader' },
// [css-loader](/loaders/css-loader)
{
loader: 'css-loader',
options: {
modules: true
}
},
// [sass-loader](/loaders/sass-loader)
{ loader: 'sass-loader' }
]
}
]
}
};
loader 执行顺序,从右到左(或从下到上)地取值(evaluate)/执行(execute)。在下面的示例中,从 sass-loader 开始执行,然后继续执行 css-loader,最后以 style-loader 为结束。
4. plugins(插件)
由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
/* uglifyJsPlugin 用来对js文件进行压缩,从而减小js文件的大小 */
new UglifyJSPlugin({
//启用文件缓存,类型:Boolean|String 默认值:false 。
//boolean:启用/禁用;String:启用文件缓存并设置缓存目录路径。
cacheDir: '.cache/',
parallel: 10,//多进程并行运行以提高构建速度.类型:Boolean|Number 默认值:false
mangle: {
screw_ie8: false //默认是true, 会把支持IE8的代码clear掉
},
mangleProperties: {
screw_ie8: false
},
compress: {
warnings: false,//删除一些无用代码的时候,不提示警告
drop_debugger: true,
drop_console: true,//过滤日志
screw_ie8: false
},
output: {
screw_ie8: false
}
})
]
}
通过配置 screw-ie8 :false 来支持IE8
5. mode(模块)
告知 webpack 使用相应模式的内置优化
module.exports = {
mode: 'production'
};
};
复制代码
production模式下会启用UglifyJsPlugin插件(移除未使用的内容和文件压缩),分别用production和development打包,编译的区别:
1.development打包后,一些没有依赖的方法 变量 文件会保留,production则会移除。
2.production打包后,代码会进行压缩,比development的文件小。
选项**** | 描述**** |
---|---|
development | 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 |
production | 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin. |
6. resolve(解析)
module.exports = {
resolve: {
extensions: ['', '.js', '.jsx', '.less', '.css', '.svg'],
alias: {
src: path.join(__dirname, '../src'),
components: path.join(__dirname, '../src/components'),
routes: path.join(__dirname, '../src/bizRoutes'),
views: path.join(__dirname, '../src/views'),
assets: path.join(__dirname, '../src/assets')
}
}
};
Extensions:自动解析确定的扩展,能够使用户在引入模块时不带扩展
Alias:创建 import 或 require 的别名,来确保模块引入变得更简单。
例如,一些位于 src/ 文件夹下的常用模块:
就像这样:
import pic_sfz_zm from '../src/assets/images/ytj/pic_sfz_zm.png';
你可以这样使用别名:
import pic_sfz_zm from 'assets/images/ytj/pic_sfz_zm.png';