webpack4+Vue搭建自己的Vue-cli項(xiàng)目過(guò)程分享
前言
對(duì)于vue-cli的強(qiáng)大,使用過(guò)的人都知道,極大的幫助我們降低了vue的入門(mén)門(mén)檻
最近在看webpack4,深感知識(shí)淺薄,這兩天也一直在思考cli的配置,借助一些別人的實(shí)踐,嘗試自己搭建vue的項(xiàng)目,這里使用webpack4版本,之前我在網(wǎng)上查找別人的vue項(xiàng)目搭建,但是都是webpack3的,所以寫(xiě)了本文,如果有錯(cuò)誤,或者有什么問(wèn)題,請(qǐng)大佬們指出
關(guān)于webpack的本文不會(huì)多說(shuō),請(qǐng)看webpack文檔
關(guān)于本文的github地址vue-MYCLI
你們的start是我發(fā)表的動(dòng)力!!!!!
前置知識(shí)
•熟悉 webpack4
•熟悉 vue
搭建基本骨架
npm init
安裝webpack4
npm install webpack webpack-cli --save-dev
在開(kāi)始之前先實(shí)驗(yàn)一下環(huán)境
根目錄新建文件 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue</title> </head> <body> <script src="./src/mian.js"></script> </body> </html>
根目錄新建文件 src/main.js
console.log("我是main");
根目錄新建文件webpack.config.js
const path = require('path')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, dist),
filename: 'index.js'
}
}
打包js文件
npx webpack --config webpack.config.js
會(huì)看到一些報(bào)錯(cuò),只要構(gòu)建成功就ok

這里說(shuō)明環(huán)境是沒(méi)有問(wèn)題的
配置初始生成環(huán)境
開(kāi)始安裝vue-loader吧
npm i webpack vue vue-loader -D //-D就是--save-dev
安裝完成后看輸出

提示安裝的依賴要安裝
npm install webpack css-loader -D
安裝完畢后新建src/app.vue
<template>
<div>
你好 {{ data }}
</div>
</template>
<script>
export default {
data(){
return {
data: "Vue"
}
}
}
</script>
<style scoped>
</style>
.vue文件是無(wú)法直接運(yùn)行的,需要在webpack里面配置loader
這里參照某課的老師的方法,html用webpack生成(后面說(shuō)明)
在根目錄新建index.js 刪除index.html
import Vue from 'vue'
import App from './app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
render: (h) => h(App)
}).$mount(root)
改寫(xiě)webpack.config.js
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'), //關(guān)于path模塊可以看看阮一峰的教程 http://javascript.ruanyifeng.com/nodejs/path.html#toc0
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js'
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader'
}]
}
}
在package里面添加腳本
"build": "webpack --config webpack.config.js"
控制臺(tái)運(yùn)行
npm run build
不出意外會(huì)報(bào)錯(cuò)

這里有2個(gè)問(wèn)題,一個(gè)是沒(méi)有指定mode 一個(gè)是沒(méi)有引用vue的插件
我們需要改寫(xiě)webpack.config.js,在config里面加一行
mode: 'production', //暫時(shí)指定為生產(chǎn)環(huán)境
再次運(yùn)行npm run build 會(huì)報(bào)錯(cuò),需要安裝一個(gè)包
這個(gè)報(bào)錯(cuò),原本在vue-loader就有提示,不知道為什么現(xiàn)在沒(méi)有,運(yùn)行之前報(bào)錯(cuò)
Error: [vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options
安裝vue-template-compiler
npm install vue-template-compiler -D
再再次運(yùn)行npm run build

假如按步驟來(lái)不除意外這里可以打包成功了~~~~
我們需要驗(yàn)證打包文件時(shí)候是否正確,所以這里使用插件HtmlWebpackPlugin,幫我們自動(dòng)創(chuàng)建html文件,并且在后續(xù)的hash文件名上很有用,具體可以看官方介紹
npm install html-webpack-plugin -D
改webpack.config.js代碼
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
var HtmlWebpackPlugin = require('html-webpack-plugin'); //引入插件
module.exports = {
mode: 'production', //暫時(shí)指定為生產(chǎn)環(huán)境
entry: path.resolve(__dirname, 'src/index.js'), //關(guān)于path模塊可以看看阮一峰的教程 http://javascript.ruanyifeng.com/nodejs/path.html#toc0
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js'
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader'
}]
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin()
]
}
npm run build打包一下,dist文件夾下面會(huì)有兩個(gè)文件

啟動(dòng)一個(gè)靜態(tài)服務(wù)器

打包Vue程序完成~~~~
至此完成了最基本的webpack配置
接下來(lái)我們要完成的的配置開(kāi)發(fā)環(huán)境
配置開(kāi)發(fā)環(huán)境
關(guān)于開(kāi)發(fā)環(huán)境以及生成環(huán)境,webpack是需要區(qū)分的,根據(jù)文檔模塊,我決定在命令里面指定模式,相應(yīng)的就將開(kāi)發(fā)環(huán)境以及生成環(huán)境分開(kāi),
這里我使用的是提起基本的webpack配置使用webpack-merge這個(gè)包來(lái)拼接我們webpack配置
npm i webpack-merge -D
修改配置文件
將各各環(huán)境的代碼區(qū)分開(kāi),webpack的結(jié)構(gòu)是這樣的

webpack.config.base.js
const path = require('path')
const config = {
entry: path.resolve(__dirname, '../src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js'
},
module: {
rules: [{
test: /\.vue$/,
loader: 'vue-loader'
}]
}
}
module.exports = config
webpack.config.build.js
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const config = merge(baseConfig ,{
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin()
]
})
module.exports = config
這里配置開(kāi)發(fā)環(huán)境就是重頭戲了,我們使用webpack-dev-server
webpack-dev-server是一個(gè)小型的Node.js Express服務(wù)器,代碼都跑在內(nèi)存里面
安裝webpack-dev-server
npm install webpack-dev-server -D
webpack.config.dev.js
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const config = merge(baseConfig, {
devServer: {
port: '8000',
host: 'localhost',
hot: true, //熱加載
//quiet: true //控制臺(tái)中不輸出打包的信息
},
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin(),
new webpack.HotModuleReplacementPlugin()
]
})
module.exports = config
最后在package里面添加腳本
"build": "webpack --mode=production --config build/webpack.config.build.js",
"dev": "webpack-dev-server --mode=development --progress --config build/webpack.config.dev.js"
執(zhí)行npm run dev查看控制臺(tái)

這就成功了,在瀏覽器里面輸入http://localhost:8000/,修改app.vue文件,實(shí)現(xiàn)了vue-cli的熱加載了~~~~
接下來(lái)完善一下,不能只有.vue文件的loader,其他的webpack也要認(rèn)識(shí)
我們配置一下圖片的loader,以及css的loader,同時(shí)css使用postcss進(jìn)行預(yù)處理
url-loader 用于將文件轉(zhuǎn)換為base64 URI file-loader是依賴loader
npm i url-loader file-loader -D
添加配置webpack.config.base.js>module>rules
{
test: /\.(gif|png|jpg|svg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 2048,
name: 'resources/[path][name].[hash:8].[ext]'
}
}]
},
配置css(vue-cli里面的實(shí)現(xiàn)非常友好,有機(jī)會(huì)可以去看看) 下面的是最簡(jiǎn)單的配置
npm install css-loader -D npm install style-loader -D npm install postcss-loader -D
添加配置webpack.config.base.js>module>rules (postcss不了解谷歌一下)
{
test: /\.css$/,
use: [
'css-loader',
'style-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true //啟用源映射支持,postcss-loader將使用其他加載器給出的先前源映射并相應(yīng)地更新它
}
}
]
}
npm install autoprefixer -D
根目錄新建文件postcss.config.js,安裝autoprefixer (自動(dòng)添加瀏覽器前綴)
const autoprofixer = require('autoprefixer')
module.exports = {
plugins: [
autoprofixer()
]
}
配置到這里基本的圖片以及css就配置完成了,運(yùn)行一下試試 npm run dev
我找src下面創(chuàng)建了assets/img/user.jpg
app.vue
<template>
<div>
你好 {{ data }}
<img src="./assets/img/user.jpg">
</div>
</template>
<script>
export default {
data(){
return {
data: "Vue Cli"
}
}
}
</script>
<style>
div{
font-size: 20px;
color: red;
}
img {
width: 100px;
}
</style>

實(shí)現(xiàn)了開(kāi)發(fā)環(huán)境的圖片以及css的配置
打包一下試試
build后生成的目錄是這樣的

這不是我們想要的,webpack把代碼,類庫(kù),css都打包在一起,這樣不管是上線還是首屏加載都有影響,所以這里我們要優(yōu)化webpack
在處理之前想安裝一個(gè)可以幫助我們每次build之前自動(dòng)刪除上次build生成的文件的插件
clean-webpack-plugin這個(gè)插件不知道為什么,怎么配置路徑都沒(méi)效果
這里我使用rimraf來(lái)進(jìn)行刪除(vue-cli也是使用rimraf,但是他是寫(xiě)在代碼里面)
npm install rimraf -D
在package里面變一下腳本,讓打包之前幫我們刪除之前到打包文件
"build-webpack": "webpack --mode=production --config build/webpack.config.build.js",
"delete": "rimraf dist",
"build": "npm run delete && npm run build-webpack"

分離打包c(diǎn)ss
它會(huì)將所有的入口 chunk(entry chunks)中引用的 *.css,移動(dòng)到獨(dú)立分離的 CSS 文件
npm install extract-text-webpack-plugin@next -D
因?yàn)殚_(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境不一樣
我們需要將css部分的代碼分環(huán)境配置
1.將原先的css配置放到webpack.config.dev.js里面
2.在webpack.config.build.js里面重寫(xiě)
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
]
})
}]
},
這樣的話,我們開(kāi)發(fā)環(huán)境不影響依舊是之前到模式,build的時(shí)候用ExtractTextPlugin幫我們分離非js文件,實(shí)現(xiàn)css的分離打包
我們打包一下試試npm run build
分離js文件
接下來(lái)是分離js文件,就是將庫(kù)文件以及我們的代碼分離開(kāi),利于上線后的瀏覽器緩存,代碼會(huì)經(jīng)常變,庫(kù)不會(huì)經(jīng)常變
在webpack4之前js分離用的插件是CommonsChunkPlugin,不過(guò)這插件現(xiàn)在移除了,現(xiàn)在用的是optimization.splitChunks 來(lái)進(jìn)行公共代碼與第三方代碼的提取,splitChunks參數(shù)如下
optimization: {
splitChunks: {
chunks: "initial", // 代碼塊類型 必須三選一: "initial"(初始化) | "all"(默認(rèn)就是all) | "async"(動(dòng)態(tài)加載)
minSize: 0, // 最小尺寸,默認(rèn)0
minChunks: 1, // 最小 chunk ,默認(rèn)1
maxAsyncRequests: 1, // 最大異步請(qǐng)求數(shù), 默認(rèn)1
maxInitialRequests: 1, // 最大初始化請(qǐng)求書(shū),默認(rèn)1
name: () => {}, // 名稱,此選項(xiàng)課接收 function
cacheGroups: { // 緩存組會(huì)繼承splitChunks的配置,但是test、priorty和reuseExistingChunk只能用于配置緩存組。
priority: "0", // 緩存組優(yōu)先級(jí) false | object |
vendor: { // key 為entry中定義的 入口名稱
chunks: "initial", // 必須三選一: "initial"(初始化) | "all" | "async"(默認(rèn)就是異步)
test: /react|lodash/, // 正則規(guī)則驗(yàn)證,如果符合就提取 chunk
name: "vendor", // 要緩存的 分隔出來(lái)的 chunk 名稱
minSize: 0,
minChunks: 1,
enforce: true,
reuseExistingChunk: true // 可設(shè)置是否重用已用chunk 不再創(chuàng)建新的chunk
}
}
}
}
官方包括這解釋,我并不是很看懂,所以打包策略并不是很好
在webpack.config.build.js>config
output: {
filename: '[name].[chunkhash:8].js'
},
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
test: /node_modules/, //這里雖然分離了,但是沒(méi)有做到按需引入,看官方配置也不是很明白
name: 'vendors',
chunks: 'all'
}
}
},
runtimeChunk: true
}
build一下查看目錄,可以看出代碼與庫(kù)之間分離了

關(guān)于eslint,我就不引入的,有興趣可以討論一下
.gitignore
這里處理一下git 新建文件.gitignore
.DS_Store node_modules/ /dist/ npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln .editorconfig,
處理一下編譯器的統(tǒng)一配置
新建文件 .editorconfig,(關(guān)于editorconfig,以及配置解釋)
root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true
還有一點(diǎn)要注意,假如沒(méi)有效果,vscode需要安裝一個(gè)插件EditorConfig for VS Code,其他編譯器不太清楚
.babelrc
處理一下ES6,以及js文件的webpack的loader配置
今天裝了babel-loader8.0.0 報(bào)錯(cuò)報(bào)一上午,心態(tài)都搞崩了,所以這里我使用的是7版本
npm install babel-loader@7 babel-core babel-preset-env -D
在webpack.config.base.js>module>rules里面添加代碼
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
新建文件 .babelrc
{
"presets": [
"env"
]
}
首先檢查開(kāi)發(fā)環(huán)境
我新建了一個(gè)es6語(yǔ)法的js 導(dǎo)入到app.vue里面

運(yùn)行結(jié)果

最后
至此,基本的vue項(xiàng)目骨架的搭建完畢了,當(dāng)然他沒(méi)有vue-cli那么強(qiáng)大,或許最大的益處是讓我們熟悉一個(gè)vue項(xiàng)目的大致webpack配置,當(dāng)然我們可以一步一步的優(yōu)化項(xiàng)目,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
vue實(shí)現(xiàn)a標(biāo)簽點(diǎn)擊高亮方法
下面小編就為大家分享一篇vue實(shí)現(xiàn)a標(biāo)簽點(diǎn)擊高亮方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
.netcore+vue 實(shí)現(xiàn)壓縮文件下載功能
這篇文章主要介紹了.netcore+vue 實(shí)現(xiàn)壓縮文件下載功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Vue打包程序部署到Nginx 點(diǎn)擊跳轉(zhuǎn)404問(wèn)題
這篇文章主要介紹了Vue打包程序部署到Nginx 點(diǎn)擊跳轉(zhuǎn)404問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
vue項(xiàng)目中使用rem替換px的實(shí)現(xiàn)示例
移動(dòng)端頁(yè)面適配,rem和vw適配方案,本文主要介紹了vue項(xiàng)目中使用rem替換px的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
vue獲取時(shí)間戳轉(zhuǎn)換為日期格式代碼實(shí)例
這篇文章主要介紹了vue獲取時(shí)間戳轉(zhuǎn)換為日期格式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
vue-cli解決IE瀏覽器sockjs-client錯(cuò)誤方法
這篇文章主要為大家介紹了vue-cli解決IE瀏覽器sockjs-client錯(cuò)誤方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
vue-cli5搭建vue項(xiàng)目的實(shí)現(xiàn)步驟
本文主要介紹了vue-cli5搭建vue項(xiàng)目的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

