写点什么

关于 Webpack4 基础配置介绍

用户头像
Chalk
关注
发布于: 2021 年 04 月 03 日

Webpack 配置

webpack 简介

1. 构建时有三种hash模式:    1. hash:每次构建都会生成一个唯一hash值,js和css同使用一个hash    2. chunkhash:根据chunk生成的hash值,如果打包来自同一个chunk,那么哈希值是一样的,  例如再index.js中引入style.css,哈希一样    3. contenthash: 根据文件的内容生成的hash值,不同文件hash值不一样,内容更改hash值变化
复制代码

第一步:

  1. 初始化 node:npm init -y 生成默认 packeage.json 文件

  2. 安装 webpack 打包:npm i wepack webpack-cli -D


   // 局部安装版本4需要安装cli     指定版本安装: npm i webpack@xxx.xx
复制代码


  1. 检查版本:npx webpack -v // 在当前项目中查找

  2. 当前项目启动: npx webpack

注意事项

当前项目启动使用 npx 启动,npm 启动的是全局 webpack


默认配置


默认入口模块:./src/index.js默认输出文件名为:main.js  默认路径为 "./dist"默认支持多种模块类型: conmmonJS esmodule AMD默认支持js模块和json模块
复制代码


自定义配置 webpack


在根目录新建文件:webpack.config.js


// 默认webpack配置文件// !使用ComminJS规范导出一个对象const path = require('path');
module.exports = { // webpack执行构建的入口 entry: './src/index.js', // 输出 output: { // 输出文件的存放路径(绝对路径) path: path.resolve(__dirname, 'dist'), // 将所有依赖的模块合并输出到main.js filename: 'main.js' }, // 模式:开发模式development/生产模式production mode: 'development', module: { rules: [] }, devServer: {}, plugins:[]};
复制代码


  // 模块处理:对象  module: {    rules: [      // !loader是有执行顺序的,自右往左      // 处理图片      // https://webpack.docschina.org/loaders/file-loader/      {        test: /\.(png|jpe?g|gif)$/i,        use: [          {            loader: 'file-loader',            options: {              name: '[name]_[hash:6].[ext]',              // 将图片统一放在一个文件夹内              outputPath: 'images'            }          }        ]      },      // 字体文件处理      {        test: /\.woff2$/,        use: [          {            loader: "file-loader"          }        ]      },      // 处理样式:https://webpack.docschina.org/loaders/style-loader/      {        test: /\.css$/,        use: [          { loader: "style-loader", options: { injectType: "singletonStyleTag" } },          "css-loader"        ]      },        /*        处理less:        https://webpack.docschina.org/loaders/less-loader/        处理CSS3兼容:        https://webpack.docschina.org/loaders/postcss-loader/        */      {        test: /\.less$/,        use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']      },        // 处理html文件的img图片      {        test: /\.html$/,        loader: 'html-loader'      },      // 处理其它资源      {        exclude: /\.(html|js|css|less|jpe?g|png|gif)/,        loader: 'file-loader',        options: {          name: '[hash:6].[ext]'        }      }    ]  }
复制代码


// 插件// 安装:npm i --save-dev html-webpack-pluginplugins: [new HtmlWebpackPlugin({    title: 'webpack',    // 模板路径    template: './src/index.html',    // 重命名    filename: 'app.html'  })]
复制代码

Plugins 插件

HtmlWebpackPlugin

打包结束自动生成一个 html 文件,并把生成的 js 模块引入


npm i --save-dev html-webpack-plugin
复制代码


const HtmlWebpackPlugin = require('html-webpack-plugin')...    new HtmlWebpackPlugin({      title: 'webpack',      template: './src/index.html',      filename: 'kkb.html'    }),

复制代码

clean-webpack-plugin

自动删除上一个 dist 目录


npm i --save-dev clean-webpack-plugin
复制代码


const { CleanWebpackPlugin } = require('clean-webpack-plugin')...plugins: [  new CleanWebpackPlugin()]
复制代码

postcss-loader autoprefixer

自动添加浏览器兼容


npm i postcss-loader autoprefixer -D
复制代码


// postcss.config.jsmodule.exports = {  plugins: [    require('autoprefixer')({      // 最近的两个版本,市场份额大于1%      overrideBrowserslist: ["last 2 versions", ">1%"]    })  ]}
复制代码

mini-css-extract-plugin

将 css 合并成一个单独的文件引入

官方文档:https://webpack.docschina.org/plugins/mini-css-extract-plugin/

将"style-loader"改为:MiniCssExtractPlugin.loader


npm i mini-css-extract-plugin -D
复制代码


const MiniCssExtractPlugin = require('mini-css-extract-plugin')module: {    rules: [      {        test: /\.less$/,        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']      }    ]},plugins: [  new MiniCssExtractPlugin()]
复制代码

optimize-css-assets-webpack-plugin

压缩 css


npm i optimize-css-assets-webpack-plugin -D
复制代码


const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')module: {    rules: [      {        test: /\.less$/,        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']      }    ]},plugins: [  new OptimizeCssAssetsWebpackPlugin()]
复制代码

开发环境性能优化

sourceMap

官方文档:https://webpack.docschina.org/configuration/devtool/

快速找到发生错误的位置

默认 development 模式 devtool: 'source-map',

默认 production 模式 devtool: 'none',

建议设置:devtool: 'eval-cheap-module-source-map'


mode: 'development',module: {rules: [...]},devtool: 'eval-cheap-module-source-map',plugins: []
复制代码

Webpack 热更新

DevServer 开发服务器

基于 webpack5

官方地址:https://webpack.docschina.org/guides/development/

自动化执行 只会在内存中编译打包,不会有任何输出


  • 仅用于开发环境,请不要在生产环境中使用它们!

  • 先将 mode 设置为 'development',并将 title 设置为 'Development'


安装:npm i webpack-dev-server -D
复制代码


  • package.json 配置


"scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "server": "webpack-dev-serve",    "start": "webpack serve --open Chrome.exe"  },
复制代码


  • webpack.config.js 配置


devServer: {  // 打包目录    contentBase: './dist',    // 是否启用gzip压缩    compress: true,    // 模块热替换    hot: true,    // 设置端口号    port: 3000  },
复制代码


  • 启动指令: npm start

HMR

模块热更新

更新修改的某个文件

默认 css 开启了 HMR

html 不需要开启,默认 js 未开启 HMR

入口文件没有 HMR 功能,只能给入口文件的依赖开启 HMR 功能


  • parint.js


export default print;function print() {  console.log('pr2ingd');}
复制代码


  • index 中使用


// 监听js文件变化开启HMRimport printMe from './print.js';if (module.hot) {  // 一旦module.hot为true 说明开启了HMR功能  module.hot.accept('./print.js', function () {      // 监听print.js变化,一旦发生变化,其它模块不会重新打包构建    console.log('Accepting the updated printMe module!');      // 执行回调函数    printMe();  })}
复制代码

Loader

js 语法检查

  • 使用 eslint-loader

  • 配置

js 语法兼容

  • 使用 babel-loader 处理

  • 配置

生产环境性能优化

优化打包构建速度

oneOf

​ 默认会将所有 loader 都过一遍,为了性能更好,使用 oneOf


  • 注意:不能有两个配置处理同一种类型文件

  • oneOf 会匹配文件处理,oneOf 中的 loader 只会匹配一个


// webpack 是基于node.js的const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// 复用CssLoader,提取样式并作兼容性处理const commonCssLoader = [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader',];
module.exports = { // webpack执行构建的入口 entry: ['./src/index.js', './src/index.html'], // 输出 output: { // 输出文件的存放路径(绝对路径) path: path.resolve(__dirname, 'dist'), // 将所有依赖的模块合并输出到main.js filename: '[name].js', }, // 模式development/production mode: 'production', // 模块处理:对象 module: { rules: [ // !loader是有执行顺序的,自右往左 // 语法检查 { test: /\.js$/, exclude: /node_modules/, // 优先执行 enforce: 'pre', loader: 'eslint-loader', options: { fix: true, }, }, { oneOf: [ // js兼容性处理:babel-loader { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { // 预设,指示babel做怎样的兼容性处理 presets: [ [ '@babel/preset-env', { // 兼容性按需加载 useBuiltIns: 'usage', corejs: { version: 3, }, // 指定兼容性版本浏览器 targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17', }, }, ], ], }, }, // 处理图片 // https://webpack.docschina.org/loaders/file-loader/ { test: /\.(png|jpe?g|gif)$/i, use: [ { loader: 'file-loader', options: { name: '[name]_[hash:6].[ext]', // 将图片统一放在一个文件夹内 outputPath: 'images', }, }, ], }, // 字体文件处理 { test: /\.woff2$/, use: [ { loader: 'file-loader', }, ], }, // 处理样式 { test: /\.css$/, use: [ ...commonCssLoader, // 将所有内联样式放在一个style里 // { loader: 'style-loader', options: { injectType: 'singletonStyleTag' } }, // 'css-loader', ], }, { test: /\.less$/, use: [...commonCssLoader, 'less-loader'], }, // 处理html文件的img图片 { test: /\.html$/, loader: 'html-loader', }, // 处理其它资源 { exclude: /\.(html|js|css|less|jpe?g|png|gif)/, loader: 'file-loader', options: { name: '[hash:6].[ext]', outputPath: 'media', }, }, ], }, ], }, devtool: 'eval-cheap-module-source-map', // 开发服务器 用来自动化 devServer: { contentBase: './dist', compress: true, hot: true, port: 3000, }, plugins: [ new HtmlWebpackPlugin({ title: 'Development', template: './src/index.html', filename: 'kkb.html', }), new CleanWebpackPlugin(), new MiniCssExtractPlugin({ // 对输出的css文件整个重命名 filename: '[name]_[chunkhash:8].css', }), new OptimizeCssAssetsWebpackPlugin(), ],};

复制代码
babel 缓存

开启 babel 缓存,第二次构建时会读取之前的缓存

用来将一些较大的 js 文件缓存

options: { cacheDirectory: true, }



{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { // 预设,指示babel做怎样的兼容性处理 presets: [ [ '@babel/preset-env', { // 兼容性按需加载 useBuiltIns: 'usage', corejs: { version: 3, }, // 指定兼容性版本浏览器 targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17', }, }, ], ], // 开启babel缓存,第二次构建时会读取之前的缓存 cacheDirectory: true, },},
复制代码


hash/chunkhash/contenthash


选择 contenthash,hash 值随文件改变而改变

优化代码运行的性能

tree shaking
  1. 去除无用 js 代码

  2. 使用条件:

  3. 必须使用 ES6 模块化

  4. 开启 production 环境

Code split

文件打包的三种方式:


  • 入口文件打包 单入口/多入口

  • 代码分隔

  • 动态导入语法/结合第二种方法 split


1.使用 split 打包,可以将 nde_modules 中代码单独打包一个 chunk 最终输出


2.自动分析多入口 chunk 中,有没有公共的文件,如果有,会单独打包一个 chunk


// 单入口entry: ['./src/index.js', './src/index.html'],// 多入口entry: {  index: './src/index.js',  text: './src/text.js'  },// 使用split打包optimization: {splitChunks: {  chunks: 'all',},},
复制代码


  1. 动态导入


通过 js 代码,让某个文件被单独打包成一个 chunk


import 动态导入语法:能将某个文件单独打包


通过 webpack 注释给打包文件命名


// 在index.js文件中或其它jsimport(/* webpackChunkName: 'test' */'./test').then(({mul, count}) => {console.log(mul(2, 5))}).catch(() => {console.log('文件加载失败!');})
复制代码
懒加载

利用代码分隔,将代码分隔放在一个异步的触发事件中 从而实现懒加载


预加载: webpackPrefetch: true


使用预加载,让网页在空闲状态下加载文件,兼容性较差(慎用)


区别:


  • 正常加载是并行加载(同一时间加载多个文件)

  • 懒加载是在事件触发时, 在使用时加载

  • 预加载是 等其它文件加载完毕之后,在浏览器空闲时再加载


// 在index.js文件中或其它jsdocumentgetElementById('btn').onclick = function() {    // 懒加载    import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test')    .then(({mul, count}) => {    console.log(mul(2, 5))    })    .catch(() => {    console.log('文件加载失败!');    })}
复制代码
PWA

渐进式网络开发应用程序(离线可访问技术)


// 插件下载npm i workbox-webpack-plugin -D
复制代码


index.js 中配置


/*  1. eslint不识别window/navigator全局变量    解决:需要修改package.json中eslintConfig配置    "env": {      "browser": true    }*/// 注册serviceWorker// 处理兼容性问题if ('serviceWorker' in navigator) {  window.addEventListener('load', () => {    navigator.serviceWorker.register('/service-worker.js')      .then(() => {        console.log('Sw注册成功');      })      .catch(() => {        console.log('Sw注册失败');      });  });}
复制代码


package.json 中配置


"eslintConfig": {    "extends": "airbnb-base",    "env": {      "browser": true    }  }
复制代码


必须运行在服务器中才能看到结果

发布于: 2021 年 04 月 03 日阅读数: 13
用户头像

Chalk

关注

万码皆同源! 2021.03.28 加入

我有一杯酒,浑浊的佳酿,含工作,含繁琐,含生活!

评论

发布
暂无评论
关于Webpack4 基础配置介绍