Webpack5正式公布也有很长长长一段时间了,上手了一段时候后发现真香。webpack5的新个性使得咱们在配置上比以往版本更加不便了,构建速度也有了质的飞跃。本文着重为大家解说从 0 到 1 搭建 vue3 + webpack 5开发环境的过程中遇到的疑难。

我的项目地址: webpack5-vue3

demo地址: https://zhouyupeng.github.io/webpack5-vue3/#/

先看一下配置好的我的项目目录构造

├─build│  ├─webpack.base.conf.js │  ├─webpack.dev.conf.js   │  ├─webpack.prod.conf.js │  ├─webpack.rules.conf.js ├─node_modules├─public|  |-index.html└─src|  ├─api|  ├─assets|  ├─components|  ├─filters|  ├─plugins|  ├─router|  ├─store|  ├─style|  ├─utils|  ├─views|  |-App.vue|  |-main.ts|-.env.dev|-.env.test|-.env.prod|-.gitigore|-babel.config.js|-package.json|-postcss.config.js

接下来,咱们应用 Webpack5 从0搭建一个残缺的 Vue3 的开发环境!

环境(environment)

webpack 5 运行于 Node.js v10.13.0+ 的版本。

本文波及到依赖的版本号

├── webpack           5.43├── webpack-cli       4.7.2├── node              14.17.0

初始化目录

第一步: 创立目录并且初始化 package.json

mkdir webpack5-vue3 && cd webpack5-vue3yarn init -y

第二步: 装置webpack三件套

yarn add webpack webpack-cli webpack-dev-server -D

留神:

  1. -D 等价于 --save-dev; 开发环境时所需依赖
  2. -S 等价于 --save; 生产环境时所需依赖

第三步:初始化目录和文件

  • 创立./build/webpack.config.js文件和./src/main.js文件并且写上webpack打包配置代码

    // webpack.config.jsconst path = require('path');module.exports = {  entry: path.resolve(__dirname, '../src/main.js'), // 入口  output: {      path: path.resolve(__dirname, '../dist'),      filename: './js/[name].[chunkhash].js',      publicPath: './',  },}
  • 在package.json的scripts里写上打包命令

    "build": "webpack --config ./build/webpack.config.js --mode production --progress --color -w"

    参数详解

  • --config或-c: 提供 webpack 配置文件的门路,例如 ./webpack.config.js
  • --mode:配置环境也可写在配置文件里 不配置mode 默认production模式打包
  • --progress: 启用在构建过程中打印编译进度
  • --color: 启用控制台色彩
  • --watch或-w: 监听文件变动

运行打包脚本yarn build看到webpack运行并且打包胜利了。

配置开发服务器

webpack5 + webpack-cli4 启动开发服务器命令与之前有所变动,从 webpack-dev-server 转变为 webpack serve,

"build": "webpack serve --config ./build/webpack.config.js --mode development --progress --color",

运行起来后呈现了另外的问题。改了代码控制台从新编译,然而热更新有效。

看一下有效的启动和无效启动之后的 network 截图比照:

网上找了一圈,说删除 package.json 里的 browserslist能够热更,截止我写这篇文章装置的依赖版本时不行,
最初在issues看到解决办法,依照官网给出的解释如同只会在webpack-dev-server@4.X中修复这个问题,这里装置beta最新版本yarn add webpack-dev-server@lastest -D,运行代码发现热更新胜利。
装置webpack-dev-server 4.X版本后配置产生了很多扭转,废除了很多以前的配置
4.x配置点我点我或者看这里

分环境打包

在咱们平时我的项目开发中,个别都会有:开发环境、测试环境、预公布环境和生产环境。当初来对 webpack 的配置文件进行环境拆分。

拆分文件
├─build│  ├─webpack.base.conf.js   //公共配置│  ├─webpack.dev.conf.js    //mode为development配置│  ├─webpack.prod.conf.js   //mode为production配置│  ├─webpack.rules.conf.js  //loader配置
配置环境变量

应用dotenv来按需加载不同的环境变量,VUE CLI3的环境变量也是应用的这个插件

  • 装置dotenv插件

    yarn add dotenv -D
  • 批改webpack.base.conf.js

    //...const envMode = process.env.envModerequire('dotenv').config({ path: `.env.${envMode}` })// 正则匹配以 VUE_APP_ 结尾的 变量const prefixRE = /^VUE_APP_/let env = {}// 只有 NODE_ENV,BASE_URL 和以 VUE_APP_ 结尾的变量将通过 webpack.DefinePlugin 动态地嵌入到客户端侧的代码中for (const key in process.env) {  if (key == 'NODE_ENV' || key == 'BASE_URL' || prefixRE.test(key)) {      env[key] = JSON.stringify(process.env[key])  }}plugins: [  //...  new webpack.DefinePlugin({ // 定义环境变量      'process.env': {          ...env      }  })]
  • 批改package.json

    "scripts": {"dev": "cross-env envMode=dev webpack serve --config ./build/webpack.dev.conf.js  --color","build": "cross-env envMode=prod webpack --config build/webpack.prod.conf.js  --color","build:test": "cross-env envMode=test webpack --config build/webpack.prod.conf.js  --color"},
  • 配置变量文件
.env.dev.env.test.env.prod

配置实现后能够像VUE CLI3一样应用环境变量了点我点我

配置外围性能

将 ES6+ 转 ES5

因为有些浏览器无奈解析 ES6+ 等高级语法,故须要将其转化为浏览器可能解析的低版本语法

yarn add @babel/core @babel/preset-env babel-loader -Dyarn add core-js -S

loader配置

// webpack.rules.conf.jsrules: [    {        test: /\.js$/,        exclude: /node_modules/,        use: {            loader: 'babel-loader',        }    }, ]

Babel 配置文件
Babel的配置文件是Babel执行时默认会在当前目录寻找的文件,次要有.babelrc,.babelrc.js,babel.config.js和package.json。它们的配置项都是雷同,作用也是一样的,只须要抉择其中一种。
举荐应用后缀名是js配置文件,因为能够应用js做一些逻辑解决,适用性更强。

// babel.config.jsconst presets = [    ["@babel/preset-env", {        "useBuiltIns": 'usage', // 这里配置usage 会主动依据你应用的办法以及你配置的浏览器反对版本引入对于的办法。        "corejs": "3.11.0" // 指定 corejs 版本     }]]const plugins = []module.exports = {    plugins,    presets}
产出HTML

装置 html-webpack-plugin 插件解决 index.html 文件,此插件的性能是依据提供的模板文件,主动生成正确的我的项目入口文件,并把 webpack 打包的 js 文件主动插入其中

yarn add html-webpack-plugin -D

plugins配置

webpack.base.conf.jsnew HtmlWebpackPlugin({    template: path.resolve(__dirname, '../public/index.html'),    filename: 'index.html',    title: 'webpack5+vue3',    minify: {        html5: true, // 依据HTML5标准解析输出        collapseWhitespace: true, // 折叠空白区域        preserveLineBreaks: false,        minifyCSS: true, // 压缩文内css        minifyJS: true, // 压缩文内js        removeComments: false // 移除正文    },    files: prodMode ? cdn.prod : cdn.dev //CDN引入文件配置}),

这里的index.html源文件放在../public/文件夹里。
留神: 配置动静网页题目时,需将模板中的 <title> 标签里的内容改成 <%= htmlWebpackPlugin.options.title %>
CDN引入js

<% for (var i inhtmlWebpackPlugin.options.files&&htmlWebpackPlugin.options.files.js) { %><script src="<%= htmlWebpackPlugin.options.files.js[i] %>"></script><% } %>
增加 css 和 sass 反对
yarn add style-loader css-loader -Dyarn add node-sass sass-loader -Dyarn add autoprefixer postcss-loader -D 

loader配置

//webpack.rules.conf.js{    test: /\.(css|scss|sass)$/,    use: [        'style-loader',        'css-loader',        'postcss-loader',        'sass-loader'    ]}

loader 从右到左(或从下到上)地取值(evaluate)/执行(execute)。在下面的示例中,从 sass-loader 开始执行,最初以 style-loader 为完结。

配置 alias 别名

创立 import 或 require 的别名,来确保模块引入变得更简略

// webpack.base.conf.jsresolve: {    alias: {        "@": path.resolve(__dirname, "../src"),        assets: path.resolve(__dirname, '../src/assets/'),        img: path.resolve(__dirname, '../src/assets/img'),        utils: path.resolve(__dirname, '../src/utils'),        api: path.resolve(__dirname, '../src/api'),    },},
解决图片等动态资源

Webpack5 之前咱们解决动态资源比方PNG 图片、SVG 图标等等,须要用到url-loader,file-loader,raw-loader。Webpack5 提供了内置的动态资源构建能力,咱们不须要装置额定的 loader,仅须要简略的配置就能实现动态资源的打包和分目录寄存。这三个loader在github上也进行了更新。

webpack5应用四种新增的资源模块(Asset Modules)代替了这些loader的性能。

asset/resource 将资源宰割为独自的文件,并导出url,就是之前的 file-loader的性能.
asset/inline 将资源导出为dataURL(url(data:))的模式,之前的 url-loader的性能.
asset/source 将资源导出为源码(source code). 之前的 raw-loader 性能.
asset 主动抉择导出为独自文件或者 dataURL模式(默认为8KB). 之前有url-loader设置asset size limit 限度实现。

//webpack.rules.conf.js{    test: /\.(png|jpg|svg|gif)$/,    type: 'asset/resource',    generator: {        // [ext]后面自带"."        filename: 'assets/[hash:8].[name][ext]',    },}

更多配置点我点我

打包时革除上次构建dist目录

webpack5.20以下版本革除dist文件内容个别应用插件 clean-webpack-plugin, 5.20版本当前output新增个性clean,用于革除dist文件

//webpack.prod.conf.jsmodule.exports = {  //...  output: {    clean: true, // Clean the output directory before emit.  },};

更多配置点我点我

动态资源输入到根目录
yarn add copy-webpack-plugin -D

当某些文件不须要通过webpack打包解决而间接应用,这里咱们能够应用 copy-webpack-plugin 这个插件,在构建的时候,将 public/ 的动态资源间接复制到 dist根目录下

//webpack.prod.conf.jsnew copyWebpackPlugin({    patterns: [{        from: path.resolve(__dirname, "../public"),        to: './',        globOptions: {            dot: true,            gitignore: true,            ignore: ["**/index.html*"],        }    }]}),
提取款式文件

本插件会将 CSS 提取到独自的文件中,为每个蕴含 CSS 的 JS 文件创建一个 CSS 文件,并且反对 CSS 和 SourceMaps 的按需加载。

yarn add mini-css-extract-plugin -D
//webpack.prod.conf.jsplugins: [//...    new miniCssExtractPlugin({        filename: './css/[name].[contenthash].css',        chunkFilename: './css/[id].[contenthash].css',    })],

批改webpack.rules.conf.js

{    test: /\.(css|scss|sass)$/,    use: [        !prodMode ? 'style-loader'            : {                loader: MiniCssExtractPlugin.loader,                options: {                    publicPath: '../',                },            },        'css-loader',        'postcss-loader',        'sass-loader',    ],},

辨认 .vue文件

yarn add vue-loader@next @vue/compiler-sfc -Dyarn add vue@next -S

留神:

  • vue-loader:它是基于 webpack 的一个的 loader 插件,解析和转换 .vue 文件,提取出其中的逻辑代码 script、款式代码 style、以及 HTML 模版 template,vue 3.x须要装置vue-loader@next。
  • @vue/compiler-sfc: Vue 2.x 时代,须要 vue-template-compiler 插件解决 .vue 内容为 ast , Vue 3.x 则变成 @vue/compiler-sfc 。

批改webpack配置

// webpack.rules.conf.jsrules: [    {        test: /\.vue$/,        use: [            'vue-loader'        ]    }]//webpack.base.conf.jsconst { VueLoaderPlugin } = require('vue-loader/dist/index');plugins: [    new VueLoaderPlugin()]

增加App.vue

<template>    <div>        <p class="title">{{title}}</p>    </div></template><script>import { defineComponent, ref } from 'vue';export default defineComponent({    setup() {        const title = ref('渐进式JavaScript 框架');        return {            title        }    }})</script><style scoped>.title{    color: #000;}</style>

批改main.js

import { createApp } from 'vue' // Vue 3.x 引入 vue 的模式import App from './App.vue' // 引入 APP 页面组建 const app = createApp(App) // 通过 createApp 初始化 appapp.mount('#root') // 将页面挂载到 root 节点

跑一遍代码,运行胜利。

装置Vue全家桶

 yarn add vue-router@4 vuex@next axios -S

vw适配

yarn add postcss-loader postcss-px-to-viewport -D

新建postcss.config.js文件

'postcss-px-to-viewport': {    unitToConvert: 'px', // 须要转换的单位,默认为"px"    viewportWidth: 750, //  设计稿的视口宽度    unitPrecision: 5, // 单位转换后保留的精度    propList: ['*'], // 能转化为vw的属性列表    viewportUnit: 'vw', //  心愿应用的视口单位    fontViewportUnit: 'vw', // 字体应用的视口单位    selectorBlackList: ['.ignore', '.hairlines', '.ig-'], // 须要疏忽的CSS选择器    minPixelValue: 1, // 最小的转换数值,如果为1的话,只有大于1的值会被转换    mediaQuery: false, // 媒体查问里的单位是否须要转换单位    replace: true, // 是否间接更换属性值,而不增加备用属性    include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//)    landscape: false, // 是否增加依据 landscapeWidth 生成的媒体查问条件 @media (orientation: landscape)    landscapeUnit: 'vw', // 横屏时应用的单位    landscapeWidth: 568 // 横屏时应用的视口宽度}

去掉生产环境console.log

应用TerserWebpackPlugin来进行去除console.log,压缩JS,webpack5之后自带最新的terser-webpack-plugin,无需再重新安装原文点我点我

//webpack.prod.conf.jsminimizer: [    new TerserPlugin({        // 多过程        parallel: true,        //删除正文        extractComments: false,        terserOptions: {            compress: { // 生产环境去除console                drop_console: true,                drop_debugger: true,            },        },    })],

编译缓存

Webpack5 内置 FileSystem Cache 能力减速二次构建,能够通过以下配置来实现

cache: {    type: 'filesystem',    // 可选配置    buildDependencies: {        config: [__filename],  // 当构建依赖的config文件(通过 require 依赖)内容发生变化时,缓存生效    },    name: '',  // 配置以name为隔离,创立不同的缓存文件,如生成PC或mobile不同的配置缓存    ...,},

配置好后第二次构建速度快的飞起。
注意事项:

  • cache 的属性 type 会在开发模式下被默认设置成 memory,而且在生产模式中被禁用,所以如果想要在生产打包时应用缓存须要显式的设置。
  • 为了避免缓存过于固定,导致更改构建配置无感知,仍然应用旧的缓存,默认状况下,每次批改构建配置文件都会导致从新开始缓存。当然也能够本人被动设置 version 来管制缓存的更新。

集成 Vant

yarn add vant@next -S
  • 按需引入

    yarn add babel-plugin-import -D
  • 批改配置

    // babel.config.jsconst plugins = [  ['import', {      libraryName: 'vant',      libraryDirectory: 'es',      style: true  }, 'vant']]
  • vant 适配vw

批改postcss.config.js

const path = require('path');module.exports = ({file}) => {    const designWidth = file.includes(path.join('node_modules', 'vant')) ? 375 : 750;    return {        plugins: {            'postcss-px-to-viewport': {                unitToConvert: 'px', // 须要转换的单位,默认为"px"                viewportWidth: designWidth, //  设计稿的视口宽度                unitPrecision: 5, // 单位转换后保留的精度                propList: ['*'], // 能转化为vw的属性列表                viewportUnit: 'vw', //  心愿应用的视口单位                fontViewportUnit: 'vw', // 字体应用的视口单位                selectorBlackList: ['.ignore', '.hairlines', '.ig-'], // 须要疏忽的CSS选择器                minPixelValue: 1, // 最小的转换数值,如果为1的话,只有大于1的值会被转换                mediaQuery: false, // 媒体查问里的单位是否须要转换单位                replace: true, // 是否间接更换属性值,而不增加备用属性                include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//)                landscape: false, // 是否增加依据 landscapeWidth 生成的媒体查问条件 @media (orientation: landscape)                landscapeUnit: 'vw', // 横屏时应用的单位                landscapeWidth: 568 // 横屏时应用的视口宽度            }        }    }}

wepback的可视化资源剖析插件

yarn add webpack-bundle-analyzer -D

用来剖析哪些模块引入了哪些代码,进行有目的性的优化代码
在打包脚本前面加--analyzeyarn build --analyze,无需另外配置。新版本webpack-cli曾经反对了。原文

最初

不晓得大家看完这篇文章,学废了吗。文章中若是有谬误或者不精确的中央,欢送大家指出探讨。

欢送关注

欢送关注小程序“进阶的大前端”,800多道前端面试题在线查看