搭建基于webpack4.0的vue項目,這篇文章就夠了

本文意在帶領讀者簡單搭建基于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

歡迎批評指正

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容