前言
最近对公司远古我的项目进行降级整顿,发现 webpack5 性能上有了很大的晋升,加上对 vue3 的应用,顺便尝试从零开始搭建一个 vue3 的开发环境,不应用官网的脚手架次要是为了加深对这套技术的了解
仓库地址
筹备工作
第一步:创立工程目录并初始化
mkdir wp5-vue3
cd wp5-vue3
npm init -y
第二步:装置 webpack
npm i webpack webpack-cli -D
这里没有抉择全局装置,大家能够依据本人的理论状况进行抉择
第三步:创立入口目录 src 及入口文件 index.js
mkdir src
touch src/index.js
轻易写点内容
// index.js
console.log('hello webpack5')
用过 webpack 的应该都晓得四个 外围概念:
- 入口(entry)
- 输入(output)
- loader
- 插件(plugins)
而 webpack 默认entry 就是根目录下 src/index.js
在输入前通过各种loader 和 plugins 对文件进行解决
最终输入到 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 数组 includes
console.log('es7:', [1,2,3].includes(1))
// ES8 对象 entries
let 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 里配置 assetModuleFilename
module.exports = {
// ...
output: {
// ...
assetModuleFilename: 'images/[hash][ext][query]'
}
}
// 第二种 在指定资源 generator 里配置 filename
module.exports = {
module: {
rules: [
{
test: /\.html/,
type: 'asset/resource',
generator: {filename: 'static/[hash][ext][query]'
}
}
]
}
}
Rule.generator.filename
与output.assetModuleFilename
雷同,并且仅实用于asset
和asset/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.ts
declare 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? · JavaScript
The 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 / Yes
Installing 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