webpack 搭建 vue 專案

tankboo發表於2017-12-27

前期準備

  1. webpack
  2. vue.js
  3. npm
  4. nodejs
  5. ES6語法

由於本文內容是通過npm來載入vue,所以開始之前需安裝nodejs環境,安裝完成之後再執行以下步驟:

建立專案

    mkdir  vue-demo
    cd vue-demo
複製程式碼

使用 npm init 命令 生成package.json檔案

npm init
複製程式碼

大概生成的package.json 如下:

{
  "name": "vue-demo",
  "version": "1.0.0",
  "description": "this is a vue demo",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "ISC",
  "dependencies": {
  }
}
複製程式碼

引入webpack ,關於如何使用webpack 請參考官網

    npm install webpack --save-dev
複製程式碼

如果使用npm下載的速度過慢,可以使用淘寶的cnpm 映象

    npm install -g cnpm –registry=https://registry.npm.taobao.org
複製程式碼

輸入以上命令即可將npm指向國內映象,使用時需將npm 替換成cnpm即可, 其他不變

在專案中建立webpack.config.js 檔案

const path = require('path')
module.exports ={
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"demo.js"
    }
}
複製程式碼

使用webpack 命令編譯

webpack
複製程式碼

編譯之後的專案目錄大概如下:

webpack 搭建 vue 專案

注意:在使用webpack命令之前 需先建立 index.html 和 main.js 檔案 其中 main.js檔案位於src 目錄下

index.html 的內容如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue demo</title>
</head>
<body>
    <script src="./dist/demo.js"></script>
</body>
</html>
複製程式碼

main.js 的內容如下

alert('hello world');
複製程式碼

引入vue

    npm install vue --save
複製程式碼

執行命令後會在package.json中新增如下程式碼

"dependencies": { "vue": "^2.4.2" }

將main.js中的內容修改為如下程式碼

import Vue from 'vue'
var vm = new Vue({
    el:'#app',
    data:{
        msg:'hello vue'
    }
})
複製程式碼

引入babel

npm install --save-dev babel-core babel-loader
複製程式碼

由於在使用vue時會用到很多es6的語法,但是現在很多瀏覽器對es6的支援不是很好,所以在編譯時需要將這些語法轉換es5的語法,此時我們使用babel來進行編譯。

babel的使用請閱讀官網文件http://babeljs.cn/。

將babel加入到webpack.config.js 配置檔案中:

const path = require('path')

module.exports ={
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"demo.js"
    },
    module:{
        rules:[
            {
                test: /\.js$/,
                loader:"babel-loader",
                exclude: /node_modules/
            }
        ]
    }
}
複製程式碼

然後命令列輸入 webpack 命令即可進行編譯,再編譯完成後用瀏覽器開啟index.html 檔案,此時會發現瀏覽器控制檯出現以下錯誤:

[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.

(found in <Root>)
複製程式碼

這是因為正在使用的是vue的執行時版本,而此版本中的編譯器時不可用的,我們需要把它切換成執行時 + 編譯的版本,需要在配置檔案中新增如下程式碼

 resolve: {
    alias: {
       'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
    }
 }
複製程式碼

此時在執行webpack 命令重新編譯,編譯後在訪問index.html頁面,頁面內容如下圖

webpack 搭建 vue 專案
此時一個基於webpack的vue 專案就搭建好。

webpack的一些常用配置

在專案的實際開發中我們還會引入css、圖片以及字型等資原始檔。這些檔案的引入都需要相應的載入器才能將其載入到專案中並正常使用。

下面只介紹部分我們需要的載入器的使用方法, 更多資訊請查閱webpack載入器文件

css載入器

我們需要引入css-loader、和style-loader (安裝style-loader的目的是為了在html中以style的方式嵌入css )。

執行命令

    npm install --save-dev css-loader style-loader
複製程式碼

在 webpack.config.js 中進行如下配置

    module: {
        rules: [{
            test: /\.js$/,
            loader: "babel-loader",
            exclude: /node_modules/
        }, {
            test: /\.css$/,
            loader: 'style-loader!css-loader'
        }]
    },
複製程式碼

然後再src 目錄下 新建一個styles的資料夾並在裡面新增一個main.css的檔案,寫上以下內容

#app{
    color:red;
}
複製程式碼

然後再執行 webpack 命令, 並重新載入index.html 檔案 ,可見css已經生效,效果如下圖

webpack 搭建 vue 專案

圖片資源的載入

使用file-loader或者url-loader載入器進行載入,他們都是用於打包檔案和圖片資源的,兩者的區別是url-loader在file-loader的基礎上進行了一次封裝。

在訪問網站時如果圖片較多,會發很多http請求,會降低頁面效能。這個問題可以通過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。相當於把圖片資料翻譯成一串字元,再把這串字元打包到檔案中,最終只需要引入這個檔案就能訪問圖片了。

當然,如果圖片較大,編碼會消耗效能。因此url-loader提供了一個limit引數,小於limit位元組的檔案會被轉為DataURl,大於limit的還會使用file-loader進行copy。

此處我們使用url-loader,由於它是基於file-loader的封裝,所以也需要引入file-loader。

npm install --save-dev file-loader url-loader
複製程式碼

webpack.config.js 的rules 中增加如下配置

{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
      limit: 10000
    }
}
複製程式碼

接下來就是將圖片引入到程式碼中,需要在main.js和index.html 分別作如下修改:

main.js

import Vue from 'vue'
import './styles/main.css'
import logo from'./images/logo.png'

var vm = new Vue({
    el:'#app',
    data:{
        logo:logo,
        msg:'hello vue'
    }
})
複製程式碼

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue demo</title>
</head>
<body>
    <div id="app">
        <img :src="logo" alt="logo" class="logo">
        {{msg}}
    </div>
    <script src="./dist/demo.js"></script>
</body>
</html>
複製程式碼

最後執行webpack 命令並訪問 index.html ,結果如下

webpack 搭建 vue 專案

在測試中發現當圖片大於10KB的時候發現載入圖片失敗,找不到圖片,但此時在dist目錄下面是能看到已經通過載入器載入成功了的圖片,再通過瀏覽器的開發者工具對圖片的引用路徑進行檢查時,可以發現頁面中img的路徑不對,路徑中只有檔名缺失了前面的dist目錄,所以此時我們需要將main.js中的程式碼進行如下修改

logo:"./dist/"+logo,
複製程式碼

重新編譯後圖片就顯示出來了。但是現在新的問題又出來了,由於我們在配置檔案中配置了小於10kb的程式碼將以 base64的形式內聯在程式碼中。所以此時是不需要 "./dist" 這個字首的。 解決此問題有兩種辦法:

  • 不使用base64的形式將圖片內嵌到程式碼中
  • 將html檔案放到dist目錄中 既然用了url-loader載入器則不推薦使用第一種。所以我們使用第二種方式。

將html檔案放到dist目錄中最簡單的辦法就是把index.html檔案複製到dist目錄中,然後將引入就是的程式碼改為:

    <script src="./demo.js" > </script>
複製程式碼

main.js中改回原來的設定

logo:logo,
複製程式碼

重新編譯後圖片在兩種情況下都可以載入出來了。

還有一中比較常用的方式是在編譯時自動在dist的目錄中建立一個html檔案並將index.html中的內容複製過去。此時我們需要時webpack的 HtmlWebpackPlugin 外掛。

HtmlWebpackPlugin 外掛

引入外掛

    npm install --save-dev html-webpack-plugin
複製程式碼

webpack.config.js 中增加如下配置

const HtmlWebpackPlugin = require('html-webpack-plugin')
...

plugins:[
     new HtmlWebpackPlugin()
]
複製程式碼

重新編譯後發現在dist目錄下生成了如下內容的html的檔案

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="demo.js"></script></body>
</html>
複製程式碼

與我們原來自己的寫index.html相比,該檔案缺少了下面這些這些內容

    <div id="app">
        <img :src="logo" alt="logo" class="logo">
        {{msg}}
    </div>
複製程式碼

現在需要對配置檔案做稍微的修改,讓html檔案在建立的時候自動將index.html的中內容複製過去。通過查閱該外掛的文件,可知需做如下修改:

plugins:[
     new HtmlWebpackPlugin({
          title: 'vue demo',
          template: 'index.html'         
     })
]
複製程式碼

index.html 檔案中 去除 script程式碼,在重新編譯後,即可獲取我們需要的html檔案

詳細引數配置請參考官方文件

webpack-dev-server

在我們實際開發中需要將程式碼部署在server中,而不是在瀏覽器中直接開啟檔案。此時我們需要使用webpack的 webpack-dev-server 。

webpack-dev-server 為我們提供了一個簡單的web伺服器,並且能夠實時重新載入(live reloading)。

    npm install --save-dev webpack-dev-server
複製程式碼

在webpack.config.js 檔案中需要指定一個資料夾,告訴開發伺服器需要從哪兒載入檔案

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "demo.js"
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'vue demo',
            template: 'index.html'
        })
    ],
    devServer:{
        contentBase:"./dist"
    },
    module: {
        rules: [{
                test: /\.js$/,
                loader: "babel-loader",
                exclude: /node_modules/
            }, {
                test: /\.css$/,
                loader: 'style-loader!css-loader'
            }, {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000
                }
            }
        ]
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
        }
    }
}
複製程式碼

上面紅色字型的配置資訊是告知webpack-dev-server, 在localhost:8080 下建立服務,將 dist 目錄下的檔案,作為可訪問檔案。

讓我們在package.json中新增一個script指令碼,可以直接執行開發伺服器(dev server):

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev":"webpack-dev-server --open",
    "build": "webpack"
  },
複製程式碼

然後輸入如下命令

    npm run dev
複製程式碼

啟動完成後,瀏覽器會自動開啟一個訪問 http://localhost:8080/ 的頁面

webpack 搭建 vue 專案

此時服務已啟動成功。

字型的載入

字型的載入方式與圖片的一樣也是用url-loader,配置如下

{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 10000
    }
 }
複製程式碼

vue-loader

在vue的開發過程中,通常我們需要寫.vue結尾的檔案即元件,如app.vue

<template>
    <div id="app">
        <img src="./images/logo2.jpg" alt="logo" >
        {{msg}}
    </div>
</template>
<script>
    export default {
        name:'app',
        data(){
            return {
                msg:"hello vue !!"
            }
        }
    }
</script>
複製程式碼

該檔案需要通過vue-loader來進行載入,現在我們需要做如下配置。通過 vue-loader 和vue-template-compiler來載入並編譯.vue檔案

npm install --save-dev vue-loader vue-template-compiler
複製程式碼

webpack.config.js 中

{
    test: /\.vue$/,
    loader: 'vue-loader'
 }
複製程式碼

為了在vue中引入對.vue的使用,我們需進行如下修改

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue demo</title>
</head>
<body>
    <div id="app">
    </div>
</body>
</html>
複製程式碼

main.js

import Vue from 'vue'
import './styles/main.css'
import App from './app.vue'

new Vue({
    el: '#app',
    template: '<App/>',
    components: { App }
})
複製程式碼

app.vue

<template>
    <div id="app">
        <img src="./images/logo.png" alt="logo" >
        {{msg}}
    </div>
</template>
<script>
    export default {
        name:'app',
        data(){
            return {
                msg: 'hello vue !!'
            }
        }
    }
</script>
複製程式碼

修改完成後 執行 npm run dev 命令 ,獲得如下效果的頁面

webpack 搭建 vue 專案

熱部署

在上一步中,如果我們修改app.vue檔案中的msg的引數,可以看到頁面會自動重新整理。但是此時是頁面全域性重新整理的,如果我們只想區域性重新整理即只重新整理修改的部分,需要使用webpack的HotModuleReplacementPlugin外掛,在webpack.config.js的plugins中新增下面的資訊:

new webpack.HotModuleReplacementPlugin()
複製程式碼

然後去package.json中,script 裡面dev的值中加上 --hot -only

    "dev": "webpack-dev-server  --hot-only --open",
複製程式碼

然後重啟服務,再修改 msg 的值,會發現此時值的改變是區域性重新整理的。

生產環境

如果我們在瀏覽器的控制檯中發現有如下提示

webpack 搭建 vue 專案
意思時說專案現在執行在開發環境中,在部署到正式環境下時,要確保它是處於production的模式。需要將程式碼打包部署到生產環境時需要進行如下配置:

var webpack = require('webpack')
module.exports = {
// ...
plugins: [
// ...
    new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: '"production"'
        }
    }),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        }
    })
]}
複製程式碼

相關文章