本文意在帶領讀者簡單搭建基于webpack4.0環境下的Vue項目,在此過程中熟悉webpack以及vue的簡單用法,請一定要按照步驟一步一步進行,循序漸進,從依賴包安裝到webpack配置到vue單文件組件的引用到最后打包發布一條龍服務包各位看官滿意;
下面坐端正,手放在電腦上,看老師,Let's go,整個過程預計在30min-45min;
最后會附上源代碼下載鏈接
第一步:安裝webpack
首先自行選擇路徑創建項目
并新建一個文件夾 webpack-vue
全局安裝webpack,安裝之前先檢查全局是否已經安裝并且確定版本
本文中 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
如果沒有安裝請自行安裝,命令如下:
yarn add webpack webpack-cli -g
第二步:項目初始化
進入項目目錄:
cd vue-learns
cd webpack-vue
yarn init -y
//新建package.json
//和npm功能類似,如果還沒安裝yarn,網上有大量教程在此不贅述
安裝vue webpack webpack-dev-server
yarn add vue (--save可省略)
yarn add webpack webpack-dev-server --dev
//--save 的意思是將模塊安裝到項目目錄下,并在package文件的dependencies節點寫入依賴。
//--dev 的意思是將模塊安裝到項目目錄下,并在package文件的devDependencies節點寫入依賴。
在項目根目錄下新建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>
在項目根目錄下新建webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {};
新建src文件夾目錄,并且在src下新建main.js,此時目錄結構如下:
webpack的思想就是一切皆模塊,官方推薦使用commonJS規范,這使得我們瀏覽器端也可以使用commonJS的模塊化寫法 :
module.exports = {}
src目錄下新建一個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', // 項目的入口文件,webpack會從main.js開始,把所有依賴的js都加載打包
output: {
path: path.resolve(__dirname, './dist'), // 項目的打包文件路徑
publicPath: '/dist/', // 通過devServer訪問路徑
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true, //historyApiFallback設置為true那么所有的路徑都執行index.html。
overlay: true // 將錯誤顯示在html之上
}
};
運行:
webpack4.0 可能會運行報錯,需要重新安裝
yarn add -D webpack-cli
yarn run dev
可以發現瀏覽器自動打開一個http://localhost:8080/ 的頁面 F12打開控制臺可以看到有hello world打出
隨意修改utils.js,可以發現瀏覽器會自動刷新
如果我們希望看打包后的bundle.js文件,運行
yarn run build
- webpack默認不支持轉碼es6,但是import export這兩個語法卻單獨支持。所以我們可以改寫前面的模塊化寫法
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'
}
}
};
重新運行npm run dev,可以看到,清一下緩存(ctrl+shift+delete),頁面正常顯示了'Hello Vue!'
第四步:引入scss和css
- webpack默認只支持js的模塊化,如果需要把其他文件也當成模塊引入,就需要相對應的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去解析
//解析器的執行順序是從下往上(先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'
],
}
]
}
};
- 注意:因為我們這里用vue開發,所以使用vue-style-loader,其他情況使用style-loader
css-loader使得我們可以用模塊化的寫法引入css,vue-style-loader會將引入的css插入到html頁面里的style標簽里
我們現在在src目錄下新建style目錄,style目錄里新建common.scss
common.scss:
body {
background: #fed;
}
main.js:
import './style/common.scss';
重新 yarn run dev ,可發現樣式生效
第五步 : 使用babel轉碼
ES6的語法大多數瀏覽器依舊不支持,bable可以把ES6轉碼成ES5語法,這樣我們就可以大膽的在項目中使用最新特性了
yarn add babel-core babel-loader babel-preset-env babel-preset-stage-3 --dev
在項目根目錄新建一個.babelrc文件
{
"presets": [
["env", { "modules": false }],
"stage-3"
]
}
webpack.config.js添加一個loader
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
//exclude表示忽略node_modules文件夾下的文件,不用轉碼
現在我們來試下async await語法吧
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();
}
});
第六步 : 引入圖片資源
把圖片也當成模塊引入
yarn add file-loader --dev
webpack.config.js添加一個loader
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
在src目錄下新建一個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 的時候我報了一個如下的錯誤,應該是由版本引起的
解決方案:
yarn add babel-loader@7 --dev
安裝完后重新 yarn run dev 便可以看見,圖片也被正確加載了
第七步:單文件組件
在前面的例子里,我們使用 Vue.component 來定義全局組件
在實際項目里,更推薦使用單文件組件
yarn add vue-loader vue-template-compiler --dev
添加一個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目錄下新建一個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 的時候又報錯了
分析:
. 參考官方文檔 https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required
. Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的,
解決:
webpack.config.js中加入 :
最后發現控制臺會報一個錯誤regeneratorRuntime is not defined,因為我們沒有安裝babel-polyfill
yarn add babel-polyfill --dev
然后修改webpack.config.js的入口
entry: ['babel-polyfill', './src/main.js'],
重新 yarn run dev ,可以發現單文件被正確加載了
第八步 source-map
在開發階段,調試也是非常重要的一項需求。
App.vue:
created() {
this.fetchData();
console.log('23333');
}
我們點擊進入這個console的詳細地址:
進入的是打包后的build.js,我并不知道是在哪個組件里寫的,這就造成了調試困難
這時就要修改webpack.config.js
module.exports = {
entry: ['babel-polyfill', './src/main.js'],
// 省略其他...
devtool: '#eval-source-map'
};
重新yarn run dev
進入控制臺,這次調試,它直接返回那個組件的源代碼了,這不是被打包過的!
第九步 打包發布
我們先試著yarn run build打包一下文件
會發現,打包后的build.js非常大,有1M多 并且提示了 [big]
在實際發布時,會對文件進行壓縮,緩存,分離等等優化處理
webpack4.x下,壓縮代碼不在webpack.config.js中寫plugins: [ new webpack.optimize.UglifyJsPlugin() ],而是在package.json中的script下面寫:
"scripts": {
"build": "webpack --mode development"
},
var path = require('path');
var webpack = require('webpack');
module.exports = {
// 省略...
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
再次重新打包
可以看見,壓縮效果非常明顯!
至此,一個非常簡單的vue開發環境搭建成功。
本文僅做參考,并且同時我也參考了很多文章也踩了一些坑(不同版本的功能是大坑啊)
讀者可以自行了解相關知識,這里只是帶領大家了解最基礎的webpack配置。
后續的vue學習便可以在此基礎上繼續深入了,加油
源代碼鏈接:
https://github.com/a307420929/webpack-vue
歡迎批評指正