webpack4教程(入门篇)

目录
一、entry、output
二、loader
三、plugin
四、mode
五、代码分离
六、懒加载
七、结果分析

系列教程
webpack4教程(初识篇)
webpack4教程(番外篇)


一、entry、output

1、entry

每个entry属性,对应一个入口文件(依赖图的开端),便于单页、多页应用的js引入。

//单入口
entry: {
    main: './src/index.js'
  }
//单入口可以简写
//entry: './src/index.js'
//多入口
entry: {
    one: './src/one/index.js',
    two: './src/two/index.js',
    three: './src/three/index.js'
  }
2、output
//单入口
//const path = require('path')
output: {
  path: path.resolve(__dirname, 'dist')
  filename: bundle.js
}
//多入口
//const path = require('path')
output: {
  path: path.resolve(__dirname, 'dist')
  filename: [name].js    //使用[name]占位符,自动识别入口文件名,从而区分打包文件名
}

PS:即使存在多入口,也只能存在一个output。

3、管理输出
//const HtmlWebpackPlugin = require('html-webpack-plugin');
//const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins: [
  new CleanWebpackPlugin(),    //每次打包前,清理dist目录
  new HtmlWebpackPlugin()    //创建html模板
] 
4、缓存

  浏览器具有缓存功能,但是缓存系统只识别文件名。当我们在服务器上,更新了文件内容,但是没有更改文件名时,浏览器则继续使用缓存文件,而不去下载新文件。因此,监听文件内容变化,实时更改产出文件名,这一做法尤为关键。
(1)使用hash值,保证文件名的唯一性

filename: '[name].[contenthash].js'

(2)提取引导模板

//打包时,会抽离出runtime部分
optimization: {
  runtimeChunk: 'single'
}

(3)防止更新一个文件,多个文件改名

//开发模式
new webpack.HashedModulesPlugin()
//生产模式
new webpack.HashedModuleIdsPlugin()

PS:只改动了一个文件的代码,但是这会改变工程文件的解析顺序。此时,就部分文件而言(如:抽离出来的第三方依赖包),尽管内容没变,但是webpack会根据解析顺序的变化,认为该文件发生了改动。因此,[contenthash]也随之变化。


二、loader

1、module.rules
//不推荐在import、cli中进行loader配置
module: {
  rules: [
    //rule
    {
      test: /\.css$/, 
      use: [
      //loader——工作顺序:尾至头
        { loader: 'style-loader' },
        {
          loader: 'css-loader',
          options: {
            modules: true
          }
        }
      ]
    }
  ]
}
2、加载css
{
  test: /\.css$/,
  use: [
    'style-loader',
    'css-loader'
  ]
}
3、加载图像
{
  test: /\.(png|svg|jpg|gif)$/,
  use: [
    'file-loader'
  ]
}
4、加载字体
{
  test: /\.(woff|woff2|eot|ttf|otf)$/,
  use: [
    'file-loader'
  ]
}
5、加载数据
{
  test: /\.(csv|tsv)$/,
  use: [
    'csv-loader'
  ]
},
{
  test: /\.xml$/,
  use: [
    'xml-loader'
  ]
}

PS:通过转换器,任何类型的模块,都可以在js中直接导入。若不使用转换器,只支持.js/.json文件导入。


三、plugin

  插件提供强大的功能,丰富webpack的打包能力。

//通过new实例,启用插件
plugins: [
  new webpack.ProgressPlugin(),    //webpack自带一系列插件
  new HtmlWebpackPlugin({template: './src/index.html'})    //使用对象,为插件配置参数
]

四、mode

模式 概述
development 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
production 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。启用 FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。
none 退出任何默认优化选项
1、开发模式

(1)映射源代码

//将编译后的代码,映射回源代码,以达到错误追踪的效果,便于调试
devtool: 'inline-source-map'    //根据需求选择devtool

(2)监听代码变化,自动编译

//不推荐使用观察模式、webpack-dev-middleware
devServer: {
  port: 3000,
  contentBase: './dist'    //在dist目录,启动服务器
}

PS:使用webpack-dev-server命令启动服务器。

(3)热替换
概述:无刷新,基于webpack-dev-server。

//配置文件
devServer: {
 hot: true
}
plugins: [
 new webpack.HotModuleReplacementPlugin()
]

//js模块
import 模块1 from './模块1'
if(module.hot) {
 //监听模块变化
 module.hot.accept('./模块1', () => {
   //调用模块1的api
 })
}

PS:由于loader已完成module.hot.accept()工作,css热加载无需手动调用module.hot.accept()。

2、生产模式

(1)tree-shaking
在生产模式下,打包过程中,会删除依赖包中,无引用的部分,按需产出精简的代码。

(2)设置副作用

//package.json
"sideEffects": false    //让webpack顺利进行tree-shaking

PS:设置副作用,只是告诉webpack,期望自己的包是没有副作用的。尽管存在副作用,也不会影响到tree-shaking

(3)映射源代码

devtool: 'source-map'

(4)压缩css

optimization: {
  minimizer: [
    new TerserJSPlugin({}),
    new OptimizeCSSAssetsPlugin({})
  ]
},
plugins: [
  new MiniCssExtractPlugin({
    filename: "[name].css",
    chunkFilename: "[id].css"
  })
],
module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader"
      ]
    }
  ]
}

PS:生产模式下,默认压缩代码。

3、双模式配置
配置文件名 概述
webpack.common.js 公共配置
webpack.dev.js 开发模式配置
webpack.prod.js 生产模式配置

(1)合并配置文件

const merge = require('webpack-merge')    //合并工具
const common = require('./webpack.common.js')
module.exports = merge(common, {
  //开发模式/生产模式专属配置
})

(2)命令

//开发模式,启动服务器
webpack-dev-server --open --config webpack.dev.js
//生产模式,打包
webpack --config webpack.prod.js

五、代码分离

1、防止重复

  多入口文件可能存在重复引入的情况,进行代码分离,抽取重复引入的代码。

//抽取重复引入的代码,到单独的文件中
optimization: {
  splitChunks: {
    chunks: 'all'
  }
}
2、预取、预加载

(1)预取

import(/* webpackPrefetch: true */ '模块');

(2)预加载

import(/* webpackPreload: true */ '模块');

(3)区别

  • preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。
  • preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
  • preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。
  • 浏览器支持程度不同。

六、懒加载

在用户交互上,动态引入代码

import('模块')    //返回promise,可以使用async+await等异步加载手段

七、结果分析

webpack stats 可交互饼图

你可能感兴趣的:(webpack4教程(入门篇))