0%

webpack用法小结

1、webpack 是什么

根据文档的定义:本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

2、webpack 四个核心概念

  • 入口(entry) 入口,webpack 执行构建的第一步将从 Entry 开始,可抽象成输入
  • 输出(output) 输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果
  • 加载器(loader) 模块转换器,用于把模块原内容按照需求转换成新内容。
  • 插件(plugins) 扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。

2.1entry

  • 定义的三种方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第一种用法
module.exports = {
entry:'index.js'
}
第二种用法
module.exports = {
entry:['index.js','b.js']
}
第三种用法
module.exports = {
entry:{
index:'index.js',
b:'b.js'
}
}

推荐使用使用第三种方法,方便分清各个入口的定义

2.2output

  • 打包成的文件
  • 一个或多个
1
2
3
4
5
6
7
8
9
10
module.exports = {
entry:{
index:'index.js',
b:'b.js'
},
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].min.[hash:5].js'
}
}

在上面的例子中,

  • output 中的 name 和 entry 中的 key 相对应
  • output 的 filename 可以指定 hash。有两个值可以选择:
    • [hash]:hash 值是特定于整个构建过程的。
    • [chunkhash]:hash 值是特定于每一个文件的内容的。
      我们理想的缓存设计是,在一次版本更新(重新构建)后,只有当一个文件的内容确实发生了变化,它才需要被重新下载,否则应使用缓存。
      因此,以上两个值中更推荐的是[chunkhash]。你也可以阅读这篇官方的缓存指南了解更多细节。

2.3loader

  • 作用: 通过使用不同的 Loader,Webpack 可以要把不同的文件都转成 JS 文件,比如 CSS、ES6/7、JSX 等
  • 参数
    • test:匹配处理文件的扩展名的正则表达式
    • use:loader 名称,就是你要使用模块的名称
    • include/exclude:手动指定必须处理的文件夹或屏蔽不需要处理的文件夹
    • query:为 loaders 提供额外的设置选项
      下面以 css-loader 为例
1
2
3
4
5
6
7
8
9
10
11
    module: {
+ rules:[
+ {
+ test:/\.css$/,
+ use:['style-loader','css-loader'],
+ include:path.join(__dirname,'./src'),
+ exclude:/node_modules/
+ }
+ ]
},

  • 常用的 loader
    • 编译相关 babel-loader ts-loader
    • 样式相关 style-loader css-loader less-loader postcss-loader
    • 文件相关 file-loader url-loader

2.4plugins

  • 参与打包的整个过程
  • 打包优化和压缩
  • 配置编译时的变量
  • 用法(以压缩 js 插件为例)
1
2
3
4
5
module.exports = {
plugins: [
new UglifyjsWebpackPlugin()
]
}
  • 常用的 plugin
    • 优化相关
      • CommonsChunkPlugin
      • UglifyjsWebpackPlugin
    • 功能相关
      • ExtractTextWebpackPlugin
      • HtmlWebpackPlugin
      • HotModuleReplacementPlugin
      • CopyWebpackPlugin

3、webpack 的常用配置

3.1 配置开发服务器

1
npm i webpack-dev-server -D
1
2
3
4
5
6
7
+ devServer:{
+ contentBase:path.resolve(__dirname,'dist'),
+ host:'localhost',
+ compress:true,
+ port:8080
+ }

  • contentBase 配置开发服务运行时的文件根目录
  • host:开发服务器监听的主机地址
  • compress 开发服务器是否启动 gzip 等压缩
  • port:开发服务器监听的端口

3.2 自动产出 html

1
npm i html-webpack-plugin -D
1
2
3
4
5
6
7
8
9
   plugins: [
+ new HtmlWebpackPlugin({
+ minify: {
+ removeAttributeQuotes:true
+ },
+ hash: true,
+ template: './src/index.html',
+ filename:'index.html'
})]
  • minify 是对 html 文件进行压缩,removeAttrubuteQuotes 是去掉属性的双引号
  • hash 引入产出资源的时候加上哈希避免缓存
  • template 模版路径

3.3 分离 css

因为 CSS 的下载和 JS 可以并行,当一个 html 文件很大的时候,我们可以把 css 单独提取出来

1
npm install --save-dev extract-text-webpack-plugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   module: {
+ rules:[
+ {
+ test:/\.css$/,
+ use: ExtractTextWebpackPlugin.extract({
+ use:'css-loader'
+ }),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
+ }
+ ]
},
plugins: [
+ new ExtractTextWebpackPlugin('css/index.css')]

3.4 编译 less 和 sass

1
2
npm i less less-loader -D
npm i node-saas sass-loader -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const cssExtract=new ExtractTextWebpackPlugin('css.css');
const lessExtract=new ExtractTextWebpackPlugin('less.css');
const sassExtract=new ExtractTextWebpackPlugin('sass.css');

{
test:/\.less$/,
use: lessExtract.extract({
use:['css-loader','less-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
{
test:/\.scss$/,
use: sassExtract.extract({
use:['css-loader','sass-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},

3.5 处理 CSS3 属性前缀

为了浏览器的兼容性,有时候我们必须加入-webkit,-ms,-o,-moz 这些前缀

  • Trident 内核:主要代表为 IE 浏览器, 前缀为-ms
  • Gecko 内核:主要代表为 Firefox, 前缀为-moz
  • Presto 内核:主要代表为 Opera, 前缀为-o
  • Webkit 内核:产要代表为 Chrome 和 Safari, 前缀为-webkit
1
npm i postcss-loader autoprefixer -D
1
2
3
4
5
6
7
8
9
10
11
12
module.exports={
plugins:[require('autoprefixer')]
}
{
test:/\.css$/,
use: cssExtract.extract({
+ use:['css-loader','postcss-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},

postcss-loader其它用法可以参考文档

3.6 转义 ES6/ES7

Babel 其实是一个编译 JavaScript 的平台,可以把 ES6/ES7,React 的 JSX 转义为 ES5

1
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
1
2
3
4
5
6
7
8
9
10
11
{
test:/\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ["env","stage-0","react"]
}
},
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},

3.7 调试打包后的代码

webapck 通过配置可以自动给我们 sourcemaps 文件,map 文件是一种对应编译文件和源文件的方法

  • source-map 把映射文件生成到单独的文件,最完整最慢
  • cheap-module-source-map 在一个单独的文件中产生一个不带列映射的 Map
  • eval-source-map 使用 eval 打包源文件模块,在同一个文件中生成完整 sourcemap
  • cheap-module-eval-source-map sourcemap 和打包后的 JS 同行显示,没有映射列
1
2
3
module.exports = {
devtool:'eval-source-map'
}

3.8watch

当代码发生修改后可以自动重新编译

1
2
3
4
5
6
7
8
new webpack.BannerPlugin(''),

watch: true,
watchOptions: {
ignored: /node_modules/, //忽略不用监听变更的目录
aggregateTimeout: 500, //防止重复保存频繁重新编译,500毫秒内重复保存不打包
poll:1000 //每秒询问的文件变更的次数
},

3.9 拷贝静态文件

有时项目中没有引用的文件也需要打包到目标目录

1
npm i copy-webpack-plugin -D
1
2
3
4
new CopyWebpackPlugin([{
from: path.join(__dirname,'public'),//静态资源目录源地址
to:'./public' //目标地址,相对于output的path目录
}]),

3.10 打包先清空

1
npm i  clean-webpack-plugin -D
1
new cleanWebpackPlugin(path.join(__dirname,'dist'))

3.11 压缩 js /css

  • 压缩 JS 可以让输出的 JS 文件体积更小、加载更快、流量更省,还有混淆代码的加密功能
    npm i uglifyjs-webpack-plugin -D
    plugins: [ new UglifyjsWebpackPlugin()]

  • webpack 可以消除未使用的 CSS,比如 bootstrap 中那些未使用的样式

1
2
npm i -D purifycss-webpack purify-css
npm i bootstrap -S
1
2
3
4
5
6
7
8
9
{
test:/\.css$/,
use: cssExtract.extract({
use: [{
loader: 'css-loader',
options:{minimize:true}
},'postcss-loader']
}),
}
1
2
3
4
+ new PurifyCSSPlugin({
+ //purifycss根据这个路径配置遍历你的HTML文件,查找你使用的CSS
+ paths:glob.sync(path.join(__dirname,'src/*.html'))
+ }),

4、总结

1
以上是webpack核心概念总结,对概念的理解,有助于总体了解下webpack不同的作用,遇到相关问题,找对应的模块。