乐趣区

关于vue.js:基于-vue3-webpack-5-sass-vw-适配方案axios-封装从0构建手机端模板脚手架

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-vue3
yarn 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.js
    const 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.envMode
    require('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 -D
yarn add core-js -S

loader 配置

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

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

// babel.config.js
const 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.js
new 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 in
htmlWebpackPlugin.options.files&&htmlWebpackPlugin.options.files.js) { %>
<script src="<%= htmlWebpackPlugin.options.files.js[i] %>"></script>
<% } %>
增加 css 和 sass 反对
yarn add style-loader css-loader -D
yarn add node-sass sass-loader -D
yarn 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.js
resolve: {
    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.js
module.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.js
new 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.js
plugins: [
//...
    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 -D
yarn 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.js
rules: [
    {
        test: /\.vue$/,
        use: ['vue-loader']
    }
]

//webpack.base.conf.js
const {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 初始化 app
app.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.js
minimizer: [
    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.js
    const 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 多道前端面试题在线查看

退出移动版