本篇文章旨在让同学们了解
Webpack的基本概念和使用方法。讲解的也会浅显易懂。
前言
在前端模块化开发的今天,我们在工作中经常会接触到一些编译构建工具,如Parcel(极速零配置Web应用打包工具),Rollup(新一代JavaScript模块打包器),Gulp(基于流的自动化构建工具),Webpack(JavaScript应用程序的静态模块打包工具)等等。这其中Webpack是用户量最庞大的一个。我们在开发Vue或React项目的时候都会接触到Webpack的配置情况。所以学好这项技术对我们的前端发展是有帮助的。
概念
本质上,Webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当 Webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。
在开始学习之前,我们先理解四个核心概念:
- entry(入口)
- output(输出)
- loader
- plugins(插件)
module.exports = {
entry:'./index',
// webpack打包入口文件
output: {
path: path.resolve(__dirname, "dist"), // string
// 所有输出文件的目标路径
filename: "[chunkhash].js", // string
// 输出的文件名称
publicPath: "/assets/", // string
// 构建文件的输出目录,可不输入。
},
module: {
rules: [
{
test: /\.js$/, // RegExp | string
loader: 'babel-loader', // 模块上下文解析
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] // 和test一样,必须匹配选项
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: './dist/index.html', // 将HTML写入的文件。默认为index.html
template: 'index.html', // webpack模板的相对或绝对路径
inject: true, // true或'body'所有javascript资源都将放置在body元素的底部。'head'会将脚本放置在head元素中
minify: { // 控制是否以及以何种方式最小化输出
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// ...
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
})
]
}
核心概念
1.entry
单入口写法:entry: string | Array<string>
module.exports = {
entry: './src/index.js'
}
多入口写法:entry: {[entryChunkName]: string} | Array<string>
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js'
}
}
2.oupput
配置output选项可以控制webpack如何向硬盘写入编译文件。注意,即使可以存在多个入口起点,但只指定一个输出配置。
在webpack中配置output属性的最低要求是,将它的值设置为一个对象,包括以下两点:
- filename 用于输出文件的文件名。
- 目标输出目录 path 的绝对路径。
module.exports = {
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
}
}
如果是多入口,output 的写法可以使用占位符(substitutions)来确保每个文件具有唯一的名称。
module.exports = {
entry: {
app: './src/app.js',
admin: './src/admin.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
3.loaders
我们先理解一下概念:loader用于对模块的源代码进行转换。loader可以使你在import或"加载"模块时预处理文件。因此loader类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader可以将文件从不同的语言(如 TypeScript)转换为JavaScript,或将内联图像转换为 data URL。loader甚至允许你直接在JavaScript模块中 import CSS文件!
module.exports = {
entry: './src/index.js' ,
output: {
filename: '[name].js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /.less$/, // 匹配使用此loader的文件
use: [ // 使用的loader名称
'style-loader',
'css-loader',
'less-loader'
]
},
{
test: /.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240
}
}
]
}
]
}
}
常用的loaders包括:
| 名称 | 描述 |
|---|---|
| babel-loader | 转换ES5,ES6,ES7等JS新特性语法 |
| style-loader | 将模块导出作为样式添加到DOM |
| css-loader | 用解析后的导入加载CSS文件并返回CSS代码 |
| less-loader | 将LESS文件编译为CSS文件 |
| ts-loader | 将TS代码转换为JS代码 |
| file-loader | 将文件打包进对应的目录,并返回相对的地址 |
| url-loader | 类似file-loader,如果文件小于限制的大小,可以返回数据的DataURL |
4.plugins
插件用于打包文件的优化,资源管理和环境变量的注入。作用于整个构建过程。插件的目的在于解决loader无法实现的其它事情
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
const webpack = require('webpack'); //访问内置的插件
module.exports = {
entry: './src/index.js' ,
output: {
filename: '[name].js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: [
'babel-loader',
]
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
常用的plugins包括:
| 名称 | 描述 |
|---|---|
| CommonsChunkPlugin | 将chunks相同的代码提取成公共js |
| cleanWebpackPlugin | 清理构建的目录 |
| HtmlWebpackPlugin | 创建html文件去承载你build后的js |
| UglifyjsWebpackPlugin | 插件使用uglify-js来压缩代码 |
| HotModuleReplacementPlugin | 启用热更新模块,也就是HMR |
| DllPlugin | 为了极大减少构建时间,进行分离打包 |
| ZipWebpackPlugin | 将打出的资源生成一个zip包 |
| TerserPlugin |
5.mode
mode用来指定当前的构建环境是:production,development,或者是none。
设置mode可以使⽤webpack内置的函数,其默认值为production。
| 选项 | 描述 |
|---|---|
| production | 设置process.env.NODE_ENV的值为production,启用FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和TerserPlugin |
| development | 设置process.env.NODE_ENV的值为development,启用NamedChunksPlugin和NamedModulesPlugin |
| none | 不开启任何优化选项 |
6.热更新机制
module.exports = {
... ,
devServer: {
contentBase: './dist',
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
总结
这里介绍了Webpack的入门实践。希望可以帮助到大家理解相关的概念。最近看知乎看到一句话挺有意思的。分享一下,原话是:“计算机教会我很多原理,我却用它来更好的生活”。