搭建基于webpack4.0的vue項(xiàng)目,這篇文章就夠了

本文意在帶領(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)指正

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昔瞧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子菩佑,更是在濱河造成了極大的恐慌自晰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稍坯,死亡現(xiàn)場(chǎng)離奇詭異酬荞,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瞧哟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)混巧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人勤揩,你說(shuō)我怎么就攤上這事咧党。” “怎么了陨亡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵傍衡,是天一觀的道長(zhǎng)深员。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蛙埂,這世上最難降的妖魔是什么倦畅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绣的,結(jié)果婚禮上叠赐,老公的妹妹穿的比我還像新娘。我一直安慰自己被辑,他們只是感情好燎悍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著盼理,像睡著了一般谈山。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宏怔,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天奏路,我揣著相機(jī)與錄音,去河邊找鬼臊诊。 笑死鸽粉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抓艳。 我是一名探鬼主播触机,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼玷或!你這毒婦竟也來(lái)了儡首?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤偏友,失蹤者是張志新(化名)和其女友劉穎蔬胯,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體位他,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氛濒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹅髓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舞竿。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖窿冯,靈堂內(nèi)的尸體忽然破棺而出骗奖,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布重归,位于F島的核電站,受9級(jí)特大地震影響厦凤,放射性物質(zhì)發(fā)生泄漏鼻吮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一较鼓、第九天 我趴在偏房一處隱蔽的房頂上張望椎木。 院中可真熱鬧,春花似錦博烂、人聲如沸香椎。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畜伐。三九已至,卻和暖如春躺率,著一層夾襖步出監(jiān)牢的瞬間玛界,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工悼吱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慎框,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓后添,卻偏偏與公主長(zhǎng)得像笨枯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子遇西,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容