前言

最近对公司远古我的项目进行降级整顿,发现webpack5性能上有了很大的晋升,加上对vue3的应用,顺便尝试从零开始搭建一个vue3的开发环境,不应用官网的脚手架次要是为了加深对这套技术的了解

仓库地址

筹备工作

第一步:创立工程目录并初始化

mkdir wp5-vue3cd wp5-vue3npm init -y

第二步:装置webpack

npm i webpack webpack-cli -D
这里没有抉择全局装置,大家能够依据本人的理论状况进行抉择

第三步:创立入口目录 src 及入口文件 index.js

mkdir srctouch src/index.js
轻易写点内容
// index.jsconsole.log('hello webpack5')

用过webpack的应该都晓得四个外围概念

  • 入口(entry)
  • 输入(output)
  • loader
  • 插件(plugins)

webpack 默认entry 就是根目录下 src/index.js

在输入前通过各种loaderplugins 对文件进行解决

最终输入到 output 指定的文件夹 默认是根目录下 dist 文件夹

所以到这里根本就是一个webpack根底的样子 通过命令行输出 webpack 则能够实现简略的打包

第四步:申明配置文件

尽管官网宣称 从 webpack v4.0.0 开始,能够不必引入一个配置文件。然而还是须要进行自定义配置,批改一些默认配置或搭配一些loader和plugins对我的项目进行解决,所以咱们在我的项目根目录申明webpack.config.js,习惯性命名 文件名没有强制规定,通过 --config 指定配置文件门路
/* * @Description: webpack.config.js * @Author: justX * @LastEditors: justX * @Date: 2021-07-28 16:15:10 * @LastEditTime: 2021-07-28 16:20:59 * @FilePath: /wp5-vue3/webpack.config.js */const path = require('path');module.exports = {    mode: 'development',    entry: './src/index.js',    output: {        filename: '[name].js',        path: path.resolve(__dirname, 'dist')    }}

批改package.json 新增 scripts 字段
"scripts": {  "build": "webpack --config 配置文件门路"}

根底配置

实现根底配置先别着急这开发,咱们丰盛一下配置让整个脚手架更好用,像日常开发中 html文件主动插入打包后的文件、本地服务实时预览、ES6+语法转换 以及 vue/less/sass等的应用, 接下来咱们就一一欠缺

创立html模板文件

通过webpack 插件 html-webpack-plugin 实现将打包后的js 主动插入到html模板

1.装置依赖

npm i html-webpack-plugin -D

2.批改配置

plugins: [  new HtmlWebpackPlugin({    template: './index.html',    filename: 'index.html',    title: 'webpack5-vue3'  })]
而后 npm run build 查看 dist 目录下的 index.html,打包后的文件曾经主动引入,咱们在浏览器查看该文件,页面失常显示 控制台也失常输入, 然而每次批改都要手动刷新,这相对是咱们不能忍耐的! 所以上面就来解决这个问题

本地服务 DevServer

通过webpack 插件 webpack-dev-server 实现本地开发服务器

1.装置依赖

npm i webpack-dev-server -D

2.批改配置

module.exports = {  //...  devServer: {    contentBase: path.join(__dirname, 'dist'),    compress: true,    port: 9000,  },};

3. 批改 package.json 新增scripts,通过CLI 调用 webpack-dev-server

 "scripts": {    "serve": "npx webpack serve",    "build": "npx webpack --config webpack.config.js"  }
  • 留神:webpack5启动开发服务器与之前版本有所区别 从 webpack-dev-server 改成了 webpack serve
而后 npm run serve 能够看到终端输入了本地服务的地址 咱们点击拜访

当初咱们批改一下 index.js 的代码内容 看看是不是会主动刷新
// ES6 箭头函数let arrowFn = () => {  console.log('es6: arrow function')};arrowFn();// ES7 数组includesconsole.log('es7:', [1,2,3].includes(1))// ES8 对象 entrieslet obj = {a: 1, b: 2, c: 3};Object.entries(obj).forEach(([key, value]) =>{  console.log('es8', key + ": " + value); // 输入a: 1, b: 2, c: 3})
然而当咱们将下面的代码运行再ie这些老版本浏览器上 会发现js报错 无奈运行,那么接下来咱们就要将 ECMAScript 2015+ 代码转换为 JavaScript 向后兼容版本的代码

ES6+语法转换

装置babel外围 、对应loader 以及预置环境

1.装置依赖

npm i @babel/core babel-loader @babel/preset-env -D

2.批改配置

module.exports = {// ...  module: {    rules: [      {        test: /\.js$/,        use: {          loader: 'babel-loader',          options: {            presets: ['@babel/preset-env']          }        }      }    ]  }}
对于babel的配置 咱们能够写在 options 里 也能够独自一个文件参考文档

款式解决

我的项目应用的预处理器是less

相干依赖 style-loader css-loader less less-loader

1.装置依赖

npm i  style-loader css-loader less less-loader -D

2.批改配置

module.exports = {// ...  module: {    rules: [      // ...      {        test: /\.css$/,        use: [          {            loader: 'style-loader',            options: {}          },          {            loader: 'css-loader',            options: {}          }        ]      },      {        test: /\.less$/,        use: [          {            loader: 'style-loader',            options: {}          },          {            loader: 'css-loader',            options: {}          },          {            loader: 'less-loader',            options: {}          }        ]      }    ]  }}

tips:多loader加载程序 是从下到上 从左到右,所以这里的程序肯定不能错哦~

至此咱们曾经解决完前端三大件 HTMl JS CSS,实现了一个网页组成的根本条件,但只是这些远远不够,接下来咱们持续欠缺 动态资源/vue3/ts/代码标准/多环境 等配置

动态资源(图片,字体,音频等)

资源模块(asset module)是一种模块类型,它容许应用资源文件(字体,图标等)而无需配置额定 loader。

在 webpack 5 之前,通常应用:

  • raw-loader 将文件导入为字符串
  • url-loader 将文件作为 data URI 内联到 bundle 中
  • file-loader 将文件发送到输入目录

资源模块类型(asset module type),通过增加 4 种新的模块类型,来替换所有这些 loader:

  • asset/resource 发送一个独自的文件并导出 URL。之前通过应用 file-loader 实现。
  • asset/inline 导出一个资源的 data URI。之前通过应用 url-loader 实现。
  • asset/source 导出资源的源代码。之前通过应用 raw-loader 实现。
  • asset 在导出一个 data URI 和发送一个独自的文件之间主动抉择。之前通过应用 url-loader,并且配置资源体积限度实现。

1.自定义输入文件名的两种形式

// 默认状况下,asset/resource 模块以 [hash][ext][query] 文件名发送到输入目录。// 有两种形式// 第一种 在output里配置 assetModuleFilenamemodule.exports = {    // ...  output: {    // ...    assetModuleFilename: 'images/[hash][ext][query]'  }}// 第二种 在指定资源 generator 里配置 filenamemodule.exports = {  module: {    rules: [      {       test: /\.html/,          type: 'asset/resource',        generator: {          filename: 'static/[hash][ext][query]'        }        }    ]  }}
Rule.generator.filenameoutput.assetModuleFilename雷同,并且仅实用于 assetasset/resource 模块类型

2.批改配置

module.exports = {  module: {    rules: [             {               test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,          type: 'asset',          parser: {            dataUrlCondition: {              maxSize: 10 * 1024 // 10kb  指定大小 小于该值则应用inline模式            }          }        },        {          test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,          type: 'asset',          parser: {            dataUrlCondition: {              maxSize: 10 * 1024 // 10kb  指定大小            }          }        },        {          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,          type: 'asset',          parser: {            dataUrlCondition: {              maxSize: 10 * 1024 // 10kb  指定大小            }          }        }    ]  }}
  • 效果图

    能够失常显示图片了 音频字体也是一样的就不一一展现了

vue3 相干配置

外围依赖/插件/loader

npm install -S vue@next vue-router@next vuex@next vue-loader@next @vue/compiler-sfc
  • vue/vue-router/vuex 三大件 对应3.*版本的
  • VueLoaderPlugin 的导入形式扭转了
  • vue-loader@next 以后须要自行指定版本(配置如下)
  • 新增了 @vue/compiler-sfc 替换原来的 vue-template-compiler
  • 相干的Webpack 配置
const { VueLoaderPlugin } = require('vue-loader')module.exports = {  ...  module: {    ...    rules: [      {        test: /\.vue$/,        use: [          {            loader: 'vue-loader'          }        ]      }    ]  },  plugins: [    ...    new VueLoaderPlugin()  ]  ...}
至此能够实现vue3的根底反对

扩大配置

Typescript

vue3更好的反对了ts, 所以这里咱们在我的项目中退出ts反对

有两种计划:

 1. npm i typescript ts-loader -D 2. babel7 版本 减少了 @babel/preset-typescript` 预设
  • 对于两种形式的区别

    可参考知乎文章 [为什么说用 babel 编译 typescript 是更好的抉择](https://zhuanlan.zhihu.com/p/376867546),自行进行抉择

之前始终用的是tsc 配置,在这里尝试一下babel7,配置如下

// 官网相干链接 // https://babeljs.io/docs/en/babel-preset-env#usebuiltins// https://babeljs.io/docs/en/babel-preset-typescript// 相干依赖"babel-loader": "^8.2.2","@babel/core": "^7.14.8","core-js": "^3.17.2","regenerator-runtime": "^0.13.9","@babel/preset-env": "^7.14.8","@babel/preset-typescript": "^7.15.0","@babel/plugin-proposal-class-properties": "^7.14.5",// babel.config.js 配置module.exports = function (api) {  api.cache(true)  const presets = [    [      '@babel/preset-env',      {        targets: 'last 1 version,> 1%,not dead',        corejs: 3,        useBuiltIns: 'usage' // 按需加载 减小打包体积 并主动引入core-js 和 regenerator-runtime      }    ],    [      '@babel/preset-typescript', // 援用Typescript插件      {        allExtensions: true // 反对所有文件扩展名,否则在vue文件中应用ts会报错      }    ]  ]  const plugins = [    '@babel/proposal-class-properties'  ]  return {    presets,    plugins  }}

src 文件夹下增加 shims-vue.d.ts 文件,解决 vue 类型报错

// shims-vue.d.tsdeclare module '*.vue' {  import type { DefineComponent } from 'vue'  const component: DefineComponent<{}, {}, any>  export default component}

Eslint

在团队开发中,正当的代码标准有利于代码保护及相互协作,但每个团对都会有本人约定而成的标准,所以这里没有唯一标准, 此处抉择初始化举荐规定
  • 初始化配置文件 【操作界面如下图】
npm install eslint eslint-webpack-plugin -D// 初始化配置文件 【操作界面如下图】> eslint --init                      ✔ How would you like to use ESLint? · problems✔ What type of modules does your project use? · esm✔ Which framework does your project use? · vue✔ Does your project use TypeScript? · No / Yes✔ Where does your code run? · browser✔ What format do you want your config file to be in? · JavaScriptThe config that you've selected requires the following dependencies:eslint-plugin-vue@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest✔ Would you like to install them now with npm? · No / YesInstalling eslint-plugin-vue@latest, @typescript-eslint/eslint-plugin@latest, @typescript-eslint/parser@latest

  • 自定义规定 可在 .eslintrc 配置文件中配置
// 自定义规定 可在 .eslintrc 配置文件中配置"rules": {  // override default options  "comma-dangle": ["error", "always"],  "indent": ["error", 2],  "no-cond-assign": ["error", "always"],  // disable now, but enable in the future  "one-var": "off", // ["error", "never"]  // disable  "init-declarations": "off",  "no-console": "off",  "no-inline-comments": "off",}
  • 引入共享配置

    须要留神 第三方共享配置自定义 须要依照第三方规定进行批改
// 或者在extends 里引入共享配置  standard/airbnb/prettier  须要装置对应依赖// 例如: npm install --save-dev eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node// 雷同规定时 前面笼罩后面"extends": [  "eslint:recommended",  "standard"  "plugin:vue/essential",  "plugin:@typescript-eslint/recommended"]
  • eslint 主动修复
// eslint 主动修复 增加webpack 脚本 具体参数查看官网文档"scripts": {  "lint": "eslint --fix --ext .ts,.js,.vue src"}

多环境

咱们我的项目个别会分为生产和测试两个环境,对应的webpack配置也肯定是不一样的,

首先,webpack本身配置 mode 就提供三种模式 ‘’ (空模式) development(测试模式) production (生产模式),具体的目标可查看: 指定mode

那么咱们根据不同模式辨别出三个文件

根底通用配置:webpack.base.config.js

测试模式配置:webpack.base.config.js

生产模式配置:webpack.base.config.js

  • 具体配置就不写进去了,大家能够自行思考一下怎么工程化这些配置,哪些是根底配置,哪些是对应模式特有的配置,依据每个plugin loader 的官网文档形容,进行对应模式的配置
  • 配置对应script

    "scripts": {  "serve": "npx webpack serve --config ./config/webpack.dev.config.js --progress ",  "build": "webpack --config ./config/webpack.prod.config.js",},

遇到的问题

  • 应用<router-view/> 组件的时候产生上面的报错,

    [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js"

    大略意思是: 组件提供模板选项,然而在Vue的这个构建中不反对运行时编译,配置你的bundler别名 vue: vue/dist/vue.esm-bundler.js

    在vue-cli脚手架其实有着一段设置 不晓得大家应用的时候有没有留神到

    具体参考 官网文档

    配置vue别名

    resolve: {  alias: {      'vue': 'vue/dist/vue.esm-bundler.js'  }}

写在最初

到此《webpack5+vue3+typescript》的根底搭建算告一段落, 此文章目标仅为搭建一个根底的vue3开发环境提供一个根底思路,理论开发的细节并不止于此,比方webpack细节配置以及开发前期都会遇到的构建速度优化问题等,特地是对于构建优化,在webpack5上相较于webpack4变动还是比拟大的,特地是在我的项目越来越大,这些优化就显得分外显著,前面有机会再写一篇对于webpack5优化的文章和他家一起学习探讨,文笔无限,若文中有谬误还望各位指出改过!

最初贴心小tips: 大家在学习新常识的时候能够参考写得好的博文,不了解的中央肯定要

看文档!

看文档!

看文档!

webpack

vue3

babel