前语
一直以来都在运用基于各种脚手架创立的项目进行开发,许多webpack的装备这些脚手架都现已帮咱们封装好了。一般情况下,脚手架提供的能力现已足够咱们运用了,有些不适用的当地看看文档改一下装备也能满足。最近一直挺好奇脚手架这个“黑盒”内部的webpack装备是怎么做的,所以就想自己搭一套相关的装备,学习一下。
文章不会过多介绍webpack相关的各种装备原理,仅仅简略记录整个进程,期望能对咱们有所协助。
话不多说,咱们开端吧。
正式开端
在开端之前请确保咱们现已装置了node和npm。推荐运用
nvm
来装置和办理node版别,本次我运用的node版别是14.20.0
一、初始化空项目
新建一个空白文件夹,然后履行yarn
的初始化指令。
mkdir vue3
cd vue3
yarn init -y
履行完咱们就得到了一个只有package.json
文件的空项目。
二、装置webpack
依靠
接下来咱们就要装置webpack相关的依靠了。在终端履行
yarn add webpack webpack-cli -D
装置的时分发现速度十分慢,咱们能够在项目下新增一个.npmrc
文件,指定下npm镜像源
装置好今后,package.json
文件的devDependencies
下就会有咱们刚刚装置好的依靠和对应的版别号
三、添加webpack
装备文件,完善根本装备
在项目根目录下新建一个webpack.config.js
文件,写一点根本的装备。
const path = require('path');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].[contenthash:8].js',
}
}
在根目录下新建src
文件夹,新建一个index.js
文件,写点根本的代码
console.log('hello world');
在package.json
文件添加scripts
字段,装备build
指令
{
"name": "vue3",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
}
}
在终端履行yarn build
,然后就能看到生成的打包好的文件啦
这个时分咱们发现生成的文件里边有许多注释之类的代码,文件体积很大,咱们需求修正webpack装备的mode
为production
。
这个mode
咱们在开发的时分期望是development
,在打包的时分是production
,咱们能够在scripts
里指定,这样就不需求每次手动修正了
修正package.json
文件
"scripts": {
"build": "NODE_ENV=production webpack"
}
然后,修正webpack.config.js
文件
// ...
module.exports = {
mode: process.env.NODE_ENV,
// ...
}
再次履行yarn build
,这个时分生成的代码就很干净了
四、运用clean-webpack-plugin
,整理旧的打包文件
上一步最终,咱们发现dist
目录下有两个main.xxx.js
文件,这是由于咱们打包了两次,所以生成了两个。咱们期望每次打包都主动删掉上次生成的文件,不要有额外的文件干扰咱们。
要完成这个功用,咱们只需求装置一个webpack的插件即可。
在终端下履行yarn add clean-webpack-plugin -D
,然后在webpack.config.js
文件里引进这个插件
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// ...
plugins: [
new CleanWebpackPlugin(),
],
}
再次履行yarn build
,这个时分咱们发现dist
目录下就只有刚刚打包好的这个文件了。
五、添加index.html
入口文件
经过上面的步骤,咱们现已能够打包根本的js文件了。接下来,咱们需求新增一个index.html文件,让它引进咱们的js文件,在浏览器里显现咱们需求的内容。
在项目根目录下新增一个template
目录,新增一个html文件。
装置html-webpack-plugin
插件,它能协助咱们主动引进打包生成好的js、css等文件到html文件中。
在终端履行yarn add html-webpack-plugin -D
,然后在webpack.config.js
文件里引进它
// ...
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...
plugins: [
new CleanWebpackPlugin(),
new HTMLWebpackPlugin({
template: './template/index.html',
}),
],
}
再次履行yarn build
,咱们发现dist
目录下多了个index.html
文件,在浏览器翻开它,发现控制台输出了hello world
注意:这儿的在浏览器翻开html文件
需求以web server
的方法翻开,而不是以file
的方法翻开。以file
的方法翻开,运用的是文件协议,在浏览器里的url是以file
最初的
如果是以web server
的方法翻开,浏览器里的url应该是以http(s)
最初的。
六、运用webpack-dev-server
进行本地调试
上面说到咱们需求以http server
的方法翻开咱们的html文件,为了更好的本地开发体会,咱们能够运用webpack-dev-server
来进行本地的开发调试。
翻开终端,履行yarn add webpack-dev-server -D
,装置所需依靠。
修正package.json
文件,添加dev
指令
"scripts": {
"dev": "NODE_ENV=development webpack serve",
"build": "NODE_ENV=production webpack"
}
咱们能够修正下webpack-dev-server
的装备,让它主动帮咱们翻开浏览器,并且添加source map
的装备,提高本地开发体会。翻开webpack.config.js
文件,装备devtool
和devServer
// ...
module.exports = {
// ...
devtool: 'eval-source-map',
devServer: {
open: true,
}
}
履行yarn dev
,在浏览器里主动翻开了http://localhost:8080
这个页面,翻开控制台,咱们发现他输出了hello world
,这便是咱们在index.js
里写的代码
七、运用vue
来编写前端代码
经过上面的几步,咱们的项目现已有了一个根本的雏形了,能够本地开发,也能够打包。接下来咱们就要运用vue
来编写前端代码,完成各种炫酷的界面和功用了。
翻开终端,顺次履行yarn add vue
,yarn add vue-loader -D
在src
目录下新建一个app.vue
文件,写一点根底的代码
<template>
<div>hello vue</div>
</template>
<script>
export default {
name: "app"
}
</script>
<style scoped>
</style>
在index.js
里引进vue
来渲染这个组件。(别忘了在index.html
里加上id
为root
的元素)
import { createApp } from 'vue';
import App from './app';
const app = createApp(App);
app.mount('#root');
然后,咱们需求在webpack.config.js
里添加module.rules
来支持解析vue
文件
// ...
module.exports = {
// ...
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
}
],
},
}
履行yarn dev
,咱们发现页面报错了
依据报错信息,咱们发现是webpack
没找到app.vue
这个文件,这是由于咱们没写文件的后缀,而webpack默认只会以.js .json .wasm
这三个后缀来找,所以找不到app.vue
这个文件。
要解决这个问题,咱们需求修正下resolve.extensions
的装备
翻开webpack.config.js
文件,新增resolve
相关的装备
// ...
module.exports = {
// ...
resolve: {
extensions: ['...', '.vue'],
},
}
再次履行yarn dev
,还是报错
这儿报了两个过错,咱们先看第二个过错,他的意思很明显,咱们需求在webpack.config.js
里引进VueLoaderPlugin
,咱们在vue-loader
的官方文档查找VueLoaderPlugin
这个关键词,能够找到相关的阐明。由于咱们的vue-loader
版别高于14
,所以咱们要手动引进这个插件
按照官方文档的阐明进行装备,修正完装备后,咱们从头履行yarn dev
,发现项目启动成功了。页面上显现出了hello vue
,可是浏览器的控制台报了一个warning
(第一个warning是我装置的浏览器插件导致的,能够疏忽)
点进去这个链接,咱们发现需求经过webpack
的DefinePlugin
来注入这两个变量
修正webpack.config.js
,添加DefinePlugin
装备
// ...
const { DefinePlugin } = require('webpack');
module.exports = {
// ...
plugins: [
// ...
new DefinePlugin({
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
}),
],
}
再次yarn dev
启动项目,warning就消失啦
八、编写款式美化界面
前端的国际必然离不开css,咱们的项目现已能够运用vue
来编写界面了,接下来就要用css
来美化它们了,让咱们编写css的装备来完成一个五彩斑斓的黑的作用吧。
装置相关loader
,在终端履行yarn add css-loader style-loader -D
;修正webpack.config.js
的module.rules
// ...
module.exports = {
// ...
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
},
{
test: /.css$/,
use: [
'style-loader',
'css-loader',
],
},
],
},
}
在app.vue
里随意写点款式
<template>
<div class="container">hello vue</div>
</template>
<script>
export default {
name: "app"
}
</script>
<style scoped>
.container {
color: #38f;
font-size: 24px;
}
</style>
从头yarn dev
,页面上就有了款式作用了。
一般情况下,咱们都会用sass
或许less
这样的语言来写款式,这儿以sass
为例
履行yarn add sass sass-loader -D
装置相应的依靠,再改下webpack.config.js
装备
module.rules
// ...
module.exports = {
// ...
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
},
{
test: /.s?css$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
],
},
}
咱们把app.vue
的style
标签的lang
特点设置成scss
<style lang="scss" scoped>
.container {
color: #38f;
font-size: 24px;
}
</style>
从头yarn dev
,页面显现正常,完美!
九、运用mini-css-extract-plugin
抽离css代码
上一步咱们成功完成了css
相关的装备,咱们运用了style-loader
来协助咱们引进咱们编写的款式,它会把咱们的css
代码以style
标签的方法刺进到index.html
文件的head
里
当咱们的代码越来越多的时分,一切的css
代码全部在index.html
里会让这个文件十分大,很臃肿。这个时分咱们能够用mini-css-extract-plugin
来帮咱们把这些css
代码抽离成独自的文件。
翻开终端,履行yarn add mini-css-extract-plugin -D
,修正webpack.config.js
,用MiniCssExtractPlugin.loader
替换掉style-loader
// ...
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /.s?css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css'
}),
],
}
再次履行yarn dev
,翻开浏览器控制台,这个时分咱们的css
代码便是经过独自的css
文件来引进的了
十、引进ant-design-vue
组件库
一般咱们都会引进一些业界成熟的组件库,具体运用哪一个就凭咱们的喜爱,这儿咱们来引进ant-design-vue
,具体的引进方法咱们参阅官方文档,这儿就不再赘述了。
十一、运用webpack asset module
处理静态资源
除了代码以外,咱们的项目里还会需求引进各种静态资源,例如图片、字体等,接下来咱们就编写对应的装备来处理这类资源。
在webpack v4
版别咱们一般需求凭借file-loader
、url-loader
来完成,而webpack v5
现已内置了这些能力,不再需求凭借第三方的loader
了,具体能够查看官方文档
修正webpack.config.js
// ...
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /.jpe?g|png|gif|webp$/,
type: 'asset',
generator: {
filename: 'assets/image/[hash:8][ext]'
}
},
{
test: /.eot|woff|woff2|ttf|svg|otf$/,
type: 'asset',
generator: {
filename: 'assets/font/[hash:8][ext]',
}
},
]
},
};
十二、编写splitChunks
装备,合理拆分代码
经过上面的步骤,咱们的项目现已具有根本的开发、调试、打包能力了,可是还有一点小小的问题能够优化一下。
翻开浏览器的控制台,切换到network
,咱们能够发现,现在生成的产物只有一个js
文件和一个css
文件,并且这个js
文件的体积十分大,这是由于咱们项目里引用的依靠例如vue
、ant-design-vue
的代码也在这个文件里。
一般而言,咱们引用的第三方依靠的版别都是不会常常变化的,而咱们如果把第三方依靠和咱们的事务代码生成到一个文件里,那么每次事务代码改变,生成的hash
就变了,浏览器会从头加载整个文件,对这些第三方依靠而言,其实是被重复加载了。
所以,为了不重复加载这些依靠,提高网页性能,常见的做法是把它们独自拆出来,生成独自的文件,这样就能使用浏览器缓存的能力
为了完成上面的功用,咱们只需修正webpack
的splitChunks
的装备即可
// ...
module.exports = {
// ...
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[/]node_modules[/]/,
// filename: 'chunks/vendor.js',
reuseExistingChunk: true,
name: (module) => {
const regExp = /[/]node_modules[/](.*?)[/]/g;
if (/javascript/ig.test(module.type)) {
const packageName = module.context.match(/[/]node_modules[/](.*?)([/]|$)/)[1];
return `npm.${packageName.replace('@', '')}`;
}
const identifier = module.identifier();
const packageName = identifier.match(regExp).pop().replace(/node_modules|[/]/ig, '');
return `npm.${packageName.replace('@', '')}`;
}
}
}
}
}
}
上面代码的大致意思便是对于node_modules
下面的模块,咱们会拿到它的包名,然后加上npm.
的前缀,例如ant-design-vue
,最终的名字便是npm.ant-design-vue.[contenthash:8].js
这样的格局。经过这样的方法,咱们就能把它们分离出来。想要进一步了解splitChunks
的内容,咱们能够参阅官方文档
再次履行yarn dev
,翻开浏览器控制台的network
部分,看看咱们装备的作用吧
结尾
以上便是本文的全部内容了,其实还有许多能够完善的当地,例如eslint
、unit test
、commitlint
、mock
等,本次就先讲到这儿,预知后事如何,请听下回分解~
喜爱的话,就点赞收藏吧~
咱们觉得有不对的当地也欢迎在谈论区留言~