本文意在帶領(lǐng)讀者簡(jiǎn)單搭建基于webpack4.0環(huán)境下的Vue項(xiàng)目同规,在此過(guò)程中熟悉webpack以及vue的簡(jiǎn)單用法友题,請(qǐng)一定要按照步驟一步一步進(jìn)行闲勺,循序漸進(jìn)绿贞,從依賴(lài)包安裝到webpack配置到vue單文件組件的引用到最后打包發(fā)布一條龍服務(wù)包各位看官滿(mǎn)意陋守;
下面坐端正废登,手放在電腦上淹魄,看老師,Let's go堡距,整個(gè)過(guò)程預(yù)計(jì)在30min-45min甲锡;
最后會(huì)附上源代碼下載鏈接
第一步:安裝webpack
首先自行選擇路徑創(chuàng)建項(xiàng)目
并新建一個(gè)文件夾 webpack-vue
全局安裝webpack兆蕉,安裝之前先檢查全局是否已經(jīng)安裝并且確定版本
本文中 webpack 版本為
4.23.0
,webpack-cli 版本為3.1.2
檢查版本命令為:
F:\vue-learns\webpack-vue>webpack -v
4.23.0
F:\vue-learns\webpack-vue>webpack-cli -v
3.1.2
如果沒(méi)有安裝請(qǐng)自行安裝搔体,命令如下:
yarn add webpack webpack-cli -g
第二步:項(xiàng)目初始化
進(jìn)入項(xiàng)目目錄:
cd vue-learns
cd webpack-vue
yarn init -y
//新建package.json
//和npm功能類(lèi)似恨樟,如果還沒(méi)安裝yarn,網(wǎng)上有大量教程在此不贅述
安裝vue webpack webpack-dev-server
yarn add vue (--save可省略)
yarn add webpack webpack-dev-server --dev
//--save 的意思是將模塊安裝到項(xiàng)目目錄下疚俱,并在package文件的dependencies節(jié)點(diǎn)寫(xiě)入依賴(lài)劝术。
//--dev 的意思是將模塊安裝到項(xiàng)目目錄下,并在package文件的devDependencies節(jié)點(diǎn)寫(xiě)入依賴(lài)呆奕。
在項(xiàng)目根目錄下新建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>Document</title>
</head>
<body>
</body>
</html>
在項(xiàng)目根目錄下新建webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {};
新建src文件夾目錄养晋,并且在src下新建main.js,此時(shí)目錄結(jié)構(gòu)如下:
webpack的思想就是一切皆模塊梁钾,官方推薦使用commonJS規(guī)范绳泉,這使得我們?yōu)g覽器端也可以使用commonJS的模塊化寫(xiě)法 :
module.exports = {}
src目錄下新建一個(gè)utils.js
module.exports = function say() {
console.log('hello world');
}
main.js :
var say = require('./utils');
say();
webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js', // 項(xiàng)目的入口文件,webpack會(huì)從main.js開(kāi)始姆泻,把所有依賴(lài)的js都加載打包
output: {
path: path.resolve(__dirname, './dist'), // 項(xiàng)目的打包文件路徑
publicPath: '/dist/', // 通過(guò)devServer訪問(wèn)路徑
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true, //historyApiFallback設(shè)置為true那么所有的路徑都執(zhí)行index.html零酪。
overlay: true // 將錯(cuò)誤顯示在html之上
}
};
運(yùn)行:
webpack4.0 可能會(huì)運(yùn)行報(bào)錯(cuò),需要重新安裝
yarn add -D webpack-cli
yarn run dev
可以發(fā)現(xiàn)瀏覽器自動(dòng)打開(kāi)一個(gè)http://localhost:8080/ 的頁(yè)面 F12打開(kāi)控制臺(tái)可以看到有hello world打出
隨意修改utils.js拇勃,可以發(fā)現(xiàn)瀏覽器會(huì)自動(dòng)刷新
如果我們希望看打包后的bundle.js文件四苇,運(yùn)行
yarn run build
- webpack默認(rèn)不支持轉(zhuǎn)碼es6,但是import export這兩個(gè)語(yǔ)法卻單獨(dú)支持方咆。所以我們可以改寫(xiě)前面的模塊化寫(xiě)法
utils.js:
export default function say() {
console.log('hello world ');
}
第三步:引入vue
main.js:
import Vue from 'vue';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
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>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="/dist/build.js"></script>
</body>
</html>
webpack.config.js :
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
重新運(yùn)行npm run dev月腋,可以看到,清一下緩存(ctrl+shift+delete)瓣赂,頁(yè)面正常顯示了'Hello Vue!'
第四步:引入scss和css
- webpack默認(rèn)只支持js的模塊化榆骚,如果需要把其他文件也當(dāng)成模塊引入,就需要相對(duì)應(yīng)的loader解析器
yarn add node-sass css-loader vue-style-loader sass-loader --dev
webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
module: {
rules: [
{ //匹配后綴名為css的文件,然后分別用css-loader煌集,vue-style-loader去解析
//解析器的執(zhí)行順序是從下往上(先css-loader再vue-style-loader)
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
],
}
]
}
};
- 注意:因?yàn)槲覀冞@里用vue開(kāi)發(fā)妓肢,所以使用vue-style-loader,其他情況使用style-loader
css-loader使得我們可以用模塊化的寫(xiě)法引入css,vue-style-loader會(huì)將引入的css插入到html頁(yè)面里的style標(biāo)簽里
我們現(xiàn)在在src目錄下新建style目錄苫纤,style目錄里新建common.scss
common.scss:
body {
background: #fed;
}
main.js:
import './style/common.scss';
重新 yarn run dev 职恳,可發(fā)現(xiàn)樣式生效
第五步 : 使用babel轉(zhuǎn)碼
ES6的語(yǔ)法大多數(shù)瀏覽器依舊不支持,bable可以把ES6轉(zhuǎn)碼成ES5語(yǔ)法,這樣我們就可以大膽的在項(xiàng)目中使用最新特性了
yarn add babel-core babel-loader babel-preset-env babel-preset-stage-3 --dev
在項(xiàng)目根目錄新建一個(gè).babelrc文件
{
"presets": [
["env", { "modules": false }],
"stage-3"
]
}
webpack.config.js添加一個(gè)loader
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
//exclude表示忽略node_modules文件夾下的文件方面,不用轉(zhuǎn)碼
現(xiàn)在我們來(lái)試下async await語(yǔ)法吧
utils.js
export default function getData() {
return new Promise((resolve, reject) => {
resolve('ok');
})
}
main.js
import getData from './utils';
import Vue from 'vue';
import './style/common.scss';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData();
}
});
第六步 : 引入圖片資源
把圖片也當(dāng)成模塊引入
yarn add file-loader --dev
webpack.config.js添加一個(gè)loader
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
在src目錄下新建一個(gè)img目錄,存放一張圖片logo.png
main.js:
import getData from './utils';
import Vue from 'vue';
import './style/common.scss';
Vue.component('my-component', {
template: '<img :src="url" />',
data() {
return {
url: require('./img/logo.png')
}
}
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue !'
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData()
}
});
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>Document</title>
</head>
<body>
<div id="app">
{{message}}
<my-component/>
</div>
<script src="/dist/build.js"></script>
</body>
</html>
在此刻我在重新 yarn run dev 的時(shí)候我報(bào)了一個(gè)如下的錯(cuò)誤色徘,應(yīng)該是由版本引起的
解決方案:
yarn add babel-loader@7 --dev
安裝完后重新 yarn run dev 便可以看見(jiàn)恭金,圖片也被正確加載了
第七步:?jiǎn)挝募M件
在前面的例子里,我們使用 Vue.component 來(lái)定義全局組件
在實(shí)際項(xiàng)目里褂策,更推薦使用單文件組件
yarn add vue-loader vue-template-compiler --dev
添加一個(gè)loader:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
}
}
在src目錄下新建一個(gè)App.vue
<template>
<div id="app">
<h1>{{ msg }}</h1>
<img src="./img/logo.png">
<input type="text" v-model="msg">
</div>
</template>
<script>
import getData from './utils';
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js'
}
},
created() {
this.fetchData();
},
methods: {
async fetchData() {
const data = await getData();
this.msg = data;
}
}
}
</script>
<style lang="scss">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
h1 {
color: #CC3333;
}
}
</style>
main.js:
import Vue from 'vue';
import App from './App.vue';
import './style/common.scss';
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
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>Document</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
此處在yarn run dev 的時(shí)候又報(bào)錯(cuò)了
分析:
. 參考官方文檔 https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required
. Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的,
解決:
webpack.config.js中加入 :
最后發(fā)現(xiàn)控制臺(tái)會(huì)報(bào)一個(gè)錯(cuò)誤regeneratorRuntime is not defined横腿,因?yàn)槲覀儧](méi)有安裝babel-polyfill
yarn add babel-polyfill --dev
然后修改webpack.config.js的入口
entry: ['babel-polyfill', './src/main.js'],
重新 yarn run dev 颓屑,可以發(fā)現(xiàn)單文件被正確加載了
第八步 source-map
在開(kāi)發(fā)階段,調(diào)試也是非常重要的一項(xiàng)需求耿焊。
App.vue:
created() {
this.fetchData();
console.log('23333');
}
我們點(diǎn)擊進(jìn)入這個(gè)console的詳細(xì)地址:
進(jìn)入的是打包后的build.js揪惦,我并不知道是在哪個(gè)組件里寫(xiě)的,這就造成了調(diào)試?yán)щy
這時(shí)就要修改webpack.config.js
module.exports = {
entry: ['babel-polyfill', './src/main.js'],
// 省略其他...
devtool: '#eval-source-map'
};
重新yarn run dev
進(jìn)入控制臺(tái)罗侯,這次調(diào)試器腋,它直接返回那個(gè)組件的源代碼了,這不是被打包過(guò)的钩杰!
第九步 打包發(fā)布
我們先試著yarn run build打包一下文件
會(huì)發(fā)現(xiàn)纫塌,打包后的build.js非常大,有1M多 并且提示了 [big]
在實(shí)際發(fā)布時(shí)讲弄,會(huì)對(duì)文件進(jìn)行壓縮措左,緩存,分離等等優(yōu)化處理
webpack4.x下避除,壓縮代碼不在webpack.config.js中寫(xiě)plugins: [ new webpack.optimize.UglifyJsPlugin() ],而是在package.json中的script下面寫(xiě):
"scripts": {
"build": "webpack --mode development"
},
var path = require('path');
var webpack = require('webpack');
module.exports = {
// 省略...
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
再次重新打包
可以看見(jiàn)怎披,壓縮效果非常明顯!
至此瓶摆,一個(gè)非常簡(jiǎn)單的vue開(kāi)發(fā)環(huán)境搭建成功凉逛。
本文僅做參考,并且同時(shí)我也參考了很多文章也踩了一些坑(不同版本的功能是大坑吧鸵肌)
讀者可以自行了解相關(guān)知識(shí)鱼炒,這里只是帶領(lǐng)大家了解最基礎(chǔ)的webpack配置。
后續(xù)的vue學(xué)習(xí)便可以在此基礎(chǔ)上繼續(xù)深入了蝌借,加油
源代碼鏈接:
https://github.com/a307420929/webpack-vue
歡迎批評(píng)指正