
前言
不讲概念性的东西,直接进入实战开发,目的让你在实践中领悟,然后再去理解概念,会事半功倍,减轻阅读成本和心理压力。为了阅读脉络更清晰,我会从3W1H原则去行文。
- what --------做什么
- who --------谁来做
- when--------什么时候做
- how---------怎么做)
背景
2019最后一篇技术文章,也是webpack4.41.5的最新落地版本,希望这篇文章能够让你真正的会用webpack4.0+,然后根据自己的理解和官网的文章、参照其他概念性的文章进阶,下面我们就一起动手实现我们的webpack脚手架吧,一起跨越2019迎接2020。
简单定义
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。 上面如果你不知道什么意思,没关系,我们直接进入实战,跟着本文亲手做一遍,或者所有的demo下载到本地跑一遍,你就理解了,如果还是不理解欢迎骚扰,文后关注我,后续解答。
实战
npx webpack打包
- what: 打包资源
- who: npx
- when: 执行npx webpack脚本打包资源的时候
- how: 当前项目命令工具下执行 npx webpack
- 项目地址: webpack-demo-4.41.5-npx-webpack
配置webpack打包
- what: 配置的方式打包资源
- who: package.json下script中配置命令行
- when: 运行npm run build的时候,打包资源的时候
- how:
"scripts": {
"build": "webpack"
}
打包资源(css、img、font、其他文件)
- what: 打包文件资源
- who: loader模块
- when: 在webpack执行文件webpack.config.js中配置,打包资源的时候
- how:
module: {
rules: [
{
test: /\.css$/, // 加载样式,嵌入html页面中
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif|jpeg)$/, // 加载图片
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/, // 加载字体库
use: {
loader: "url-loader",
options: {
limit: 50000
}
}
},
{
test: /\.(csv|tsv)$/,// 加载数据 CSV TSV格式
use: [
'csv-loader'
]
},
{
test: /\.xml$/, // 加载xml格式
use: [
'xml-loader'
]
}
]
}
手动配置文件打包
- what: 手动配置多文件打包
- who: 在入口文件index.html中写死打包后的文件名
- when: 在webpack.config.js中配置输出文件,执行打包输出的时候
- how:
// webpack.config.js
const path = require('path');
module.exports = { // 多个文件同时打包,生成多个对应的包
entry: {
app: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].bundle.js', // 这里的name动态的循环遍历entry的名字
path: path.resolve(__dirname, 'dist')
}
};
// index.html src根据entry中手动配置
<!doctype html>
<html>
<head>
<title>Output Management</title>
<script src="./print.bundle.js"></script>
</head>
<body>
<script src="./app.bundle.js"></script>
</body>
</html>
问题来了,手动配置如果entry中文件配置名发生变化或删掉多个入口,index.html内script还有跟着改,很麻烦啊,下面就要用到插件了
插件打包
- what: 利用插件进行自动化打包输出文件
- who: 插件HtmlWebpackPlugin覆盖原文件,另一个插件CleanWebpackPlugin删除dist文件
- when: npm run build打包的时候,执行对应的插件
- how:
plugins: [
new CleanWebpackPlugin(),// 最新写法
new HtmlWebpackPlugin({ // 动态生成index.html覆盖原来的index.html
title: 'Output Management from dragon'
})
]
热加载HMR
- what: 代码改动,动态局部加载 HMR(模块热替换)
- who: webpack自带的插件HotModuleReplacementPlugin、NamedModulesPlugin
- when: npm run dev的时候,启动本地开发服务
- how: 安装对应的插件然后引入
new webpack.NamedModulesPlugin(), // webpack自带的插件 以便查看修补patch依赖
new webpack.HotModuleReplacementPlugin()
环境分离与合并
- what: 为了便于维护,分离不同的环境开发环境和生产环境以及公用的部分,然后利用模块webpack-merge打包
- who: webpack-merge模块做个环境的合并
- when: 当运行不同的脚本时,npm run dev、npm run build
- how: 安装对应的插件然后引入
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
hot: true
},
plugins: [
new webpack.NamedModulesPlugin(), // webpack自带的插件 以便查看修补patch依赖
new webpack.HotModuleReplacementPlugin()
]
});
拆分代码打包
- what: 重复引用包或重复代码时,我们就要分开打包减少包的体积,提高构建效率
- who: webpack4.0以后自带配置optimization
- when: npm run build的时候
- how: 在webpack.config下配置参数即可
optimization: { // 拆分代码 提取公用的引用包
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial', // initial初始块 async按需加载 all所有
minChunks: 1 // 引用的最小个数
}
}
}
}
总结
以上是本文的实战部分,每部分都有一个完整的可运行的项目,自行动手效果会更好些。
下一节,将谈谈webpack性能优化的部分,以及开发一个给予多技术栈的脚手架。
通过上面的介绍,希望给你一些建设性的参考,有任何问题欢迎骚扰,加入【前端突击】,长按二维码关注,或微信搜索 前端突击 一起探讨前端的边界
欢迎关注,【前端突击】猎鹰突击,迎难而上,期待你的加入...
