基於 vue3 + webpack 5 + sass+ vw 適配方案+axios 封裝,從0構建手機端模板腳手架

Webpack5正式發佈也有很長長長一段時間了,上手了一段時候後發現真香。webpack5的新特性使得咱們在配置上比以往版本更加方便了,構建速度也有了質的飛躍。本文着重爲你們講解從 0 到 1 搭建 vue3 + webpack 5開發環境的過程當中遇到的疑問。css

項目地址: webpack5-vue3html

demo地址: zhouyupeng.github.io/webpack5-vu…前端

先看一下配置好的項目目錄結構vue

├─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 的開發環境!html5

環境(environment)node

webpack 5 運行於 Node.js v10.13.0+ 的版本。webpack

本文涉及到依賴的版本號ios

├── webpack           5.43
├── webpack-cli       4.7.2
├── node              14.17.0
複製代碼

初始化目錄

第一步: 建立目錄而且初始化 package.jsongit

mkdir webpack5-vue3 && cd webpack5-vue3
yarn init -y
複製代碼

第二步: 安裝webpack三件套github

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 截圖對比: gPONlR.png gPxobq.png

網上找了一圈,說刪除 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;// vant團隊是根據375px的設計稿去作的
    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多道前端面試題在線查看

相關文章
相關標籤/搜索