Vue + Webpack 構建模塊化開發框架詳解

文章指南

概要

先在文章開頭,做一個總結式的說明,這篇文章主要是講在前端模塊化開發模式中如何用Webpack這樣流行的打包器來爲當下一個很火熱的框架——vue.js,構建一個項目框架。本文例子是一個基本的Demo,想構建更爲複雜和高維護性的框架,請參考Webpack官網Guide教程

前提

要看懂本文的Demo,需要你掌握或瞭解以下內容:

當然還有htmlcssjs的基礎,但是相信讀者如果在查閱vue或者webpack相關內容,說明已經掌握了基本的技能

Demo構建過程框架

  1. 確保你的環境正確,筆者這裏的環境是node v10.12.0npm 6.4.1webpack 4.27.1webpack-cli 3.1.2
  2. 新建項目目錄,並npm初始化項目
  3. 新建webpack.config.js配置文件,並寫入項目框架配置
  4. 按照各項依賴包(加載器loader,插件plugindev工具等),包括vuevue-loadervue-template-compiler
  5. 編寫邏輯代碼和*.vue組件,我們這裏僅做了一個示範,沒有複雜業務邏輯
  6. 啓用webpack官方的dev工具dev-server,開啓一個開發模式的小服務器
  7. 啓用webpack監聽模式,自動構建和編譯項目

通過以上7步,我們就可以構建一個簡單高效的vue模塊化開發框架了

構建過程


說明一下:筆者的webpack和webpack-cli都是全局安裝的,但有時候會出現某些webpack依賴包`not 
found`的問題,這時候可能是因爲webpack4中把webpack-cli工具分離開了,導致可能在全局找不
到cli這時候先執行`npm link webpack` 和 `npm link webpack-cli`將他們加入全局環境執行


npm初始化項目

cmd

mkdir webpackVue
cd webpackVue
npm init

根據命令行的提示,填寫package name, version ,description ,entry point等信息

clipboard.png

構建結果如下:

clipboard.png

新建webpack.config.js,並寫入配置

現在的項目結構如下:

clipboard.png

我們來看看這個webpack.config.js裏都有什麼?

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');

module.exports = {
    mode : 'development',
    entry : {
        index : './src/index.js'
    },
    output : {
        filename : '[name].bundle.js',
        path : path.resolve(__dirname,'dist'),
        publicPath : './'
    },
    module : {
        rules : [
            {
                test : /\.css$/,
                use : ['style-loader','css-loader']
            },
            {
                test : /\.html$/,
                loader : 'html-loader'
            },
            {
                test : /\.vue$/,
                loader : 'vue-loader'
            }
        ]
    },
    resolve : {
        alias : {
            vue : 'vue/dist/vue.js'
        }
    },
    plugins : [
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            title : 'vue+webpack模塊化開發簡例',
            filename : 'index.html',
            template : './src/index.html',
        }),
        new webpack.HotModuleReplacementPlugin(),
        new CleanWebpackPlugin(['dist'])
    ],
    devtool : 'inline-source-map',
    devServer : {
        contentBase : './dist',
        watchContentBase : true,
        compress : true,
        port : 8080,
        hot : true,
        open : true,
    }

}

mode : 有三個值可以設置,development/production/none,一般來說我們常用的就是developmentproduction,這裏我們設爲開發模式

entry :譯爲入口,這裏配置的是我們webpack從哪裏開始分析我們項目中包的依賴,從哪裏開始打包我們的文件,入口可以不只一個,多入口的用法請參見官方文檔entry points,我這裏僅以一個入口爲例

output :對應與entry,這是告訴webpack把我們打包後的文件放到哪裏,這裏的

  • filename 是 打包後文件的名字,[name].bundle.js其中[name]表示原文件的名稱
  • path 是 指將我們的項目打包到當前文件夾的dist文件夾下
  • publicPath 是 對應於打包後模板中引入的文件的一個公共目錄,什麼意思呢?比如這裏的./,通過這個配置,則打包之後的index.html文件中引入js的路徑就會統一加上./,這個在下面還會提到👇

module.rules :這裏是配置加載loader的,簡單來說,loader是一個除js資源外的資源加載器,比如常用的css-loader/style-loader/html-loader等,默認情況下,webpack是隻能認得js文件的,所以就需要一些額外的loader來加載不是js資源的文件,比如我們這裏vue的單文件組件是.vue後綴,所以我們要引入vue-loader(這是vue官方給的一個webpack加載器),有關loder更多內容請參見官方文檔Loader

resolve.alias :這個是爲了解決import Vue from 'vue';時默認引入的是vue.common.js,而非vue.js。這裏是個大坑,Vue 最早會打包生成三個文件,一個是 runtime only 的文件 vue.common.js,一個是 compiler only 的文件 compiler.js,一個是 runtime + compiler 的文件 vue.js。但是vue在package.jsonmain屬性中指向的是dist/vue.common.js。這就導致了,構建項目之後會出現,如下錯誤:

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

關於這個問題,這裏有一篇追根溯源的博客可以看一看,Vue wran:You are using the runtime-only build of Vue...

plugins : webpack本身也是構建在插件之上的,插件的功能可以很強大,做到一些加載器做不到的事情

  • VueLoaderPlugin : 讓vue-loader發揮魔力的插件,這是官方給的說法
  • HtmlWebpackPlugin : 這是一個可以自動生成html的插件,可以免去了我們自己在./dist中寫一個html,更多內容看npm社區的介紹html-webpack-plugin
  • webpack.HotModuleReplacementPlugin : 啓用webpack的熱模塊替換的插件,關於熱模塊替換,看官方網站Hot Module Replacement
  • CleanWebpackPlugin : 這個插件可以指定每次構建清除之前的構建文件,這個可以讓我們的dist文件夾裏看起來更整潔

devtool : 此配置控制是否以及如何生成源映射。這裏的inline-source-map是相對耗費資源的一個選項,一般只在開發模式使用,這個可以將錯誤定位到文件和行級,可以很方便的debug,更多內容devTool

devServer : 這個屬性是配置webpack的一個官方dev工具,webpack-dev-server,這是一個小型的服務器,可以在在指定端口運行,爲了可以快速的搭建一個應用,不用在用Node API 寫一個服務器了,更多內容devServer

內容還真不少,webpack的配置雖然繁雜但是靈活性也是很高的,如果不想自己手動搭vue的項目框架,vue-cli可以是你的選擇。以上內容,閱讀後若不明白,可以去官方文檔查閱後,或者你也可以選擇繼續向下,因爲看完整篇內容可以構建一個大概的印象

創建項目結構,安裝各項依賴包

根據我們webpack.config.js中的配置,我們的項目結構就像這樣一樣:

clipboard.png

其中

  • dist是webpack打包後的文件存放目錄
  • src是我們源文件存放目錄

現在,讓我們來安裝你在webpack中配置的各項所需的依賴包/加載器/dev工具等,安裝的命令看起來很簡單:

cmd or powershell

npm install --save clean-webpack-plugin html-webpack-plugin vue vue-loader

npm install --save-dev css-loader html-loader style-loader vue-template-compiler webpack-dev-server

我們這裏直接,一次性裝好了所有的依賴,當然探索的過程要比這個看似簡單的兩行艱辛的多。這裏要注意vue-template-compiler是vue編譯模板<template></template>必需的,不要忘記安裝

這裏npm install的參數--save--save-dev的區別就是,save是生產環境依賴的包,而save-dev是開發環境依賴的包,之所以這樣分開是爲了,既滿足開發時便捷工具的需求又滿足了真實發布時爲了提高性能精簡依賴包的需求

好了,我們來看看,安裝好依賴後,我們的項目發生了那些變化?

clipboard.png

package-lock.json是一個清單文件,我們不需要關注它,我們來看看package.json發生了什麼

package.json

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "vue-router",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "lvbingxu",
  "license": "ISC",
  "dependencies": {
    "clean-webpack-plugin": "^1.0.0",
    "html-webpack-plugin": "^3.2.0",
    "vue": "^2.5.21",
    "vue-loader": "^15.4.2"
  },
  "devDependencies": {
    "css-loader": "^2.0.0",
    "html-loader": "^0.5.5",
    "style-loader": "^0.23.1",
    "vue-template-compiler": "^2.5.21",
    "webpack-dev-server": "^3.1.10"
  }
}

我們看到,我們的package.json文件隨着我們的安裝會自動添加上相應的依賴配置,而我們上面所說的savesave-dev參數就是分別對應這裏的dependenciesdevDependencies,如果npm不加參數,默認爲save參數

tips : package.json是一個json格式的文件,和js的json對象支持不一樣,請勿在json文件中出現不符合json格式的字符串,比如註釋// /**/,或是在最後一項後加上,

編寫業務邏輯,使用Vue單頁組件

現在我們的項目結構就像這樣:

clipboard.png

我們來看看源文件代碼:

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Test</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

index.js

import Vue from 'vue';
import App from './app.vue';
// 
new Vue(App).$mount('#app');

app.vue

<template>
    <p>{{ greeting }} VUE!!!</p>
</template>

<script>
    module.exports = {
        data : function(){
            return {
                greeting : 'Hello'
            }
        }
    }
</script>
<style  scoped>
    p {
        font-size: 2em;
        text-align: center;
    }
</style>

vue知識不再贅述,一句也講不完,如果不清楚,請移步vue官方網站,這裏的業務代碼很簡單,就是將一個<p></p>掛載到模板對應的<div id="app">上去

好了,到這裏我們已經基本把框架構建好了,終於到可以構建一下看看了

webpack打包項目,並查看打包後index.html

cmd or powershell

webpack --mode=development

以開發模式打包項目,因爲在webpack.config.js中已經配置過mode,所以默認就是開發模式。我們來看看,打包後的項目結構:

clipboard.png

我們來用瀏覽器打開/dist/index.html看看webpack是否將vue打包成功

clipboard.png

看來我們是成功了,到此爲止,我們已經從無到有構建了一個webpack打包的vue項目,但是他還不完整,我們在做個補充!

開啓一個dev-server服務器,並開啓webpack的監聽模式

爲了讓開發如虎添翼,我們每次手動的在cmd or powershell中輸入webpack --mode=development或是 webpack --mode=production顯然是很煩人的,我們可以通過在package.json中添加腳本來簡化命令,如下:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development",
    "buildp": "webpack --mode=production"
  },
tips : 注意這裏"buildp"的最後不能加上,,這對應了上一個tips的說法

這樣我們可以運行npm run build或者npm run buildp分別代替webpack --mode=developmentwebpack --mode=production

當然,你發現這還是沒有多方便,不急,我們可以開啓webpack的監聽模式,如下:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development",
    "buildp": "webpack --mode=production",
    "watch": "webpack --watch"
  },

當我們運行npm run watch後,這個進程會監聽你的文件改變,一旦有文件的改動,webpack會自動幫你打包項目,無需手動輸入了

除此之外,我們還可以開啓dev-server,一個小型的服務器,並開啓熱替換模塊,這樣無需手動刷新瀏覽器就可以實現視圖更新了,是不是很厲害!這個demo中使用了熱模塊替換,但是筆者還未成功,有待進一步研究,下一篇博客再見,這裏這是開啓了dev-server服務器,讓我們看看如何開啓:

webpack.config.js

    devServer : {
        contentBase : './dist',
        watchContentBase : true,
        compress : true,
        port : 8080,
        hot : true,
        open : true,
    }

在你的配置中的最後加入devServer的配置,我們再在package.json中加入一個腳本:

package.json

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development",
    "buildp": "webpack --mode=production",
    "watch": "webpack --watch",
    "server": "webpack-dev-server --open"
  },

讓我們執行,npm run server,發現error,別急,這是因爲我們的CleanWebpackPlugin將我們的dist文件夾清除了,我們在重新build一下

clipboard.png

可見,我們的dev-server正在監聽8080端口,we success!

後續

  到此,我係統的詳細的講述了,如何使用webpack構建一個vue的項目框架,希望讀者從中受益。我們其實可以看到,我們費了這麼大的功夫,其實頁面只是一個<p>Hello VUE!!!</p>,可能你會說是不是有些小題大作了,拿這個demo中的例子來說確實是這樣,但是這也是模塊化開發和傳統式開發的區別,對於小的項目或者需求我們確實不用這麼小題大做,但是隨着頁面的增多,業務需求的擴張和不確定性增大,我們不得不考慮代碼的維護和複用,這在傳統式開發中很難做到足夠優秀的,但是模塊化可以

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章