webpack4+vue打包簡單入門

前言

最近在研究使用webpack的使用,在查閱了數篇文章後,學習了webpack的基礎打包流程.css

原本就能夠一刪了之了,可是以爲未免有點惋惜,因此就有了這篇文章,供你們參考.html

webpack打包的教程具備時效性,有很多做者在一直維護一篇文章.超過必定時間參考價值就會降低,但願各位瞭解這一點.vue

使用的依賴一覽

"devDependencies": {
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.3",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.17",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.0",
"webpack-merge": "^4.1.4"
},
"dependencies": {
"vue": "^2.5.17"
}

都是目前最新的穩定版本.node

講解到的內容

  1. webpack的安裝
  2. webpack簡單配置
  3. vue的安裝以及使用
  4. 使用插件
  5. 提取css
  6. 使用多個配置文件
  7. 簡單的代碼分離

構建目錄

咱們建立一個新的目錄(learnwebpack).在下面建立src文件夾和一個index.html.webpack

而後咱們使用npm init命令初始化一個package.json文件,直接一路回車過去就行了.git

目錄結構:github

  • learnwebpackweb

    • src
    • index.html
    • package.json

src保存咱們未經編譯的源碼.npm

index.html內容以下:json

<!DOCTYPE html>
<html>
<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>Webpack4 && Vue</title>
</head>
<body>
    <div id="root">
        
    </div>

    <script src="./dist/app.bundle.js"></script>
</body>
</html>

安裝webpack

在webpack4中不只僅須要安裝webpack自己,還須要安裝webpack-cli.

npm install webpack webpack-cli --save-dev

使用--save-dev參數會將這兩個包添加到package.json的開發依賴中.

webpack4的特性

在webpack4中能夠實現0配置打包,也就是說不須要任何設置就能夠完成簡單的打包操做.

此外最實用的特性之一就是mode配置選項用於告訴webpack輸出模式是開發仍是產品,提供了已經預先定義好的經常使用配置.

後面的例子中咱們會使用到mode.

webpack的簡單配置

咱們在當前目錄下新建一個webpack的配置文件webpack.config.js.

此時的目錄結構爲:

  • learnwebpack

    • src
    • index.html
    • webpack.config.js
    • package.json

webpack.config.js的內容:

const {join:pathJoin} = require('path');
module.exports = {
    entry:{
        app:'./src/index.js' // 入口文件的位置
    },
    output:{
        filename:'[name].bundle.js', // 輸出文件名字的格式
        path:pathJoin(__dirname,'./dist') // 輸出的絕對路徑
    },
}

爲何會有filename上的格式

對於咱們當前的應用來講好像沒有任何用途,打包後文件名徹底能夠和入口同樣.

使用不一樣的文件名能夠解決相同文件名稱致使的瀏覽器緩存問題.

對於咱們當前這個格式來講,打包後的文件名稱爲app.bundle.js.

此外還有一些額外的模板符號:

  • [hash] 模塊標識符(module identifier)的 hash
  • [chunkhash] chunk 內容的 hash
  • [name] 模塊名稱
  • [id] 模塊標識符(module identifier)
  • [query] 模塊的 query,例如,文件名 ? 後面的字符串

如今讓咱們在src文件夾下新建一個index.js,只寫一行簡單的代碼用於測試:

console.log('hello world!');

此時的目錄結構爲:

  • learnwebpack

    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

爲何使用index.js

webpack4中零配置的默認入口位置就是當前配置路徑下的./src/index.js,也就是說若是不指定入口的狀況下也是能夠打包的.

構建咱們的項目

運行:

./node_modules/.bin/webpack-cli --config webpack.config.js

上方的命令有點冗長,咱們使用package.json中scripts字段來定義一個快捷方式.

package.json:

{
  +++
  "scripts": {
    "build": "webpack --config webpack.config.js"
  }
  +++
}

+++ 表示package.json的其餘字段,這部分目前不用關心.

如今運行這條簡化的命令,效果和上方同樣.

npm run build

對於npm版本高於5.2.0的同窗能夠嘗試使用npm的附帶模塊npx.

npx能夠直接運行./node_modules/.bin/下的內容而沒必要輸入路徑.

npx webpack --config webpack.config.js

若是操做正確你的目錄下應該會多出一個dist文件夾,內部有一個app.bundle.js文件.

此時的目錄結構:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • index.js
    • index.html
    • webpack.config.js
    • package.json

咱們能夠運行index.html了,若是一切順利.那麼在控制檯中應該會出現hello world!.

錯誤

當咱們打包的時候webpack4會報錯,緣由就是咱們沒有指定上文中提到的mode屬性,webpack默認將他設置爲production.

此時若是你查看代碼,就會發現代碼是通過壓縮的,這是webpack4的默認行爲之一.

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

安裝Vue

使用npm安裝:

npm -i vue

vue是運行時依賴,webpack須要合適loader將vue文件解釋爲webpack能夠理解的格式用於構建,因此咱們須要vue-loader來轉換vue單文件.

使用npm安裝vue-loader:

npm install vue-loader --save-dev

vue單文件中分爲三個部分,其中template部分須要專用的插件進行轉換.

安裝vue-template-compiler:

npm install  vue-template-compiler --save-dev

這個使用vue-loader自動調用的插件,也是官方默認的,不須要任何配置.

若是你不使用他,打包的時候會報錯.

簡單來講他的功能是將template部分的模板轉爲render函數.

而後咱們須要處理css,vue-loader須要css-loader才能夠運行.

安裝css-loader:

npm install css-loader --save-dev

css-loader的做用僅僅是將css轉爲webpack能夠解釋的類型,若是咱們須要將樣式使用起來插入到html中,必須使用額外的插件.

安裝vue-style-loader:

npm install vue-style-loader --save-dev

vue-style-loader是由vue官方維護的你也可使用其餘的loader來處理css,他除了提供了常見的插入樣式到html的功能之外還提供了其餘的功能,例如熱更新樣式等.

修改配置

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin'); // +++
module.exports = {
    mode:'production',
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].bundle.js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader'] // +++
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // +++
            }
        ]
    },
    plugins:[
        new VueLoaderPlugin() // +++
    ]
}

須要注意的是VueLoaderPluginvue-loaderv15的版本中,這個插件是必須啓用的.

修改目錄結構以及文件

咱們在src下建立一個pages文件夾而且在內部建立一個app.vue文件.

此時的目錄結構:

  • learnwebpack

    • dist

      • app.bundle.js
    • src

      • pages

        • app.vue
      • index.js
    • index.html
    • webpack.config.js
    • package.json

app.vue文件內容:

<style>
.test > p {
  background-color: aqua;
}
</style>

<template>
    <article class="test">
        <p>{{vue}}</p>
    </article>
</template>

<script>
export default {
  data() {
    return {
      vue: "vue"
    };
  }
};
</script>

app.vue是由index.js引用的,回過頭來咱們修改index.js:

import Vue from 'vue'
import App from './pages/app.vue';

new Vue({
    el:'#root',
    render:h=>h(App)
})

激動人心的時候到了,若是一切順利你的vue應用應該打包完成了,運行index.html就能夠查看這個結果了.

使用插件

回顧前面的一個話題,指定輸出文件名字格式.若是你將咱們的內容放到一個服務器上運行,你會很容易發現一個問題.

就是緩存,web上的資源瀏覽器會對其進行緩存,可是對開發的時候,或者產品中的代碼更新十分不友好,新的代碼不會獲得及時的使用.

咱們讓資源每次的名字不同就能夠簡單的解決這個問題,接下來修改咱們的webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
    +++
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    +++
}

此時再次修改代碼打包每次的名字都不會同樣.

可是出現了另一個問題因爲資源名字每次都不一致,每次我都須要手動指定index.html中引用的資源,這個時候該html-webpack-plugin出場了.

這個插件能夠自動生成一個html文件,而且將資源文件按照正確順序插入到html中.

安裝html-webpack-plugin:

npm install html-webpack-plugin --save-dev

webpack.config.js添加配置

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',// 指定模板html文件
            filename:'index.html'// 輸出的html文件名稱
        }),
        new VueLoaderPlugin()
    ]
}

而後咱們把index.html重命名爲template.html,將template.html中的script標籤刪除.

指定模板後HtmlWebpackPlugin會保留原來html中的內容,並且會在新生成的html文件中把script插入到合適的位置.

HtmlWebpackPlugin補充

注意:HtmlWebpackPlugin必須位於插件數組的首位.

運行項目

你會發如今dist目錄下會有index.html文件,而咱們打包後的index.js的輸出文件名也變成了app.XXXXXXXXXXXXXXXX.js的格式,更加神奇的是在index.html中自動插入了script標籤來引用打包後的js文件.

使用CleanWebpackPlugin插件

當你屢次打包的時候,你會發現因爲使用hash來命名輸出的文件每次的文件名稱都不同,致使文件愈來愈多.

使用CleanWebpackPlugin能夠每次構建前清空輸出目錄.

安裝:

npm install clean-webpack-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])// +++ 運行前刪除dist目錄
    ]
}

如今不管運行幾回構建dist目錄下都是乾淨的.

提取css

如今咱們來將vue單文件中的css提取出來到一個單獨的css文件中.

webpack4中完成這個功能的插件是mini-css-extract-plugin.

安裝:

npm install mini-css-extract-plugin --save-dev

webpack.config.js:

const {join:pathJoin} = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// +++
module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash]].js',
        path:pathJoin(__dirname,'./dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // +++
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new MiniCssExtractPlugin({
            filename:'style.css' // 指定輸出的css文件名.
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

運行咱們的項目,如今dist目錄下已經有一個style.css的文件了,並且htmlwebpackplugin自動將style.css插入到了index.html中.

使用多個配置

考慮如下問題:

  • 開發的時候咱們但願打包速度快,有源代碼提示,有熱重載(本篇文章沒有涉獵)...
  • 發佈產品咱們但願輸出的內容不會被緩存,有代碼壓縮...

是時候使用多個配置了,一個用於開發一個用於生產.

可是咱們還能夠作的更好使用webpack-merge插件,能夠將多個配置合成.

安裝webpack-merge:

npm install webpack-merge --save-dev

首先咱們定義一個包含基本信息的webpack配置文件,這個文件被其餘配置文件依賴.

webpack.common.js:

const {join:pathJoin} = require('path');
const CleanWebpackPlugin = require("clean-webpack-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:{
        app:'./src/index.js'
    },
    output:{
        filename:'[name].[hash].js',
        path:pathJoin(__dirname,'./dist')
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'template.html',
            filename:'index.html'
        }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin(['dist'])
    ]
}

能夠看到這裏定義的都是最基本的信息.

而後咱們定義開發配置而且在內容使用webpack-merge插件和webpack.config.js進行合併.

webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development', // 不壓縮代碼,加快編譯速度
    devtool: 'source-map', // 提供源碼映射文件調試使用
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader'] // 使用vue-style-loader直接插入到style標籤中
            }
        ]
    },
})

定義生產配置.

webpack.prod.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = merge(common,{
    mode:'production', // 壓縮代碼
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader // 提取css到外部文件中
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename:'style.css'
        })
    ]
})

最後修改一下咱們package.json中的快捷方式:

+++
"scripts": {
    "dev": "webpack --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
},
+++

刪除以前的webpack.config.js.

完成後的目錄結構:

  • learnwebpack

    • dist
    • src

      • pages

        • app.vue
      • index.js
    • package.json
    • template.html
    • webpack.common.js
    • webpack.dev.js
    • webpack.prod.js

嘗試運行npm run devnpm run build吧.

簡單的代碼分離

咱們在index.js中引用了Vue,若是你查看打包後的代碼你會發現vue自己會被打包到同一個文件中,若是咱們有另一個文件也引用了vue一樣的會被打包到該文件中.

顯然咱們的代碼依賴vue,可是vue不該該存在兩份,若是能夠將vue單獨提取出來就行了,這個問題就是要代碼分離.

在webpack4中刪除了原來的CommonsChunkPlugin插件,內部集成的optimization.splitChunks選項能夠直接進行代碼分離.

修改webpack.dev.js:

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'source-map',
    optimization:{ // +++
        splitChunks:{ // +++
            chunks:'initial' // +++ initial(初始塊)、async(按需加載塊)、all(所有塊)

        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                use: ['vue-loader']
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader','css-loader']
            }
        ]
    },
})

咱們要作的就是將打包後寫入到index.html的文件從目前的一個文件拆分紅多個,而且寫入到index.html中.

也就是說在入口處分離代碼.

運行:

npm run dev

你會發如今dist目錄下多出了一個文件保存着vue,另一個文件中保存着咱們編寫的代碼.

參考

vue部分:

https://cn.vuejs.org/v2/guide...
https://vue-loader.vuejs.org/zh/
https://www.npmjs.com/package...

webpack部分:

https://webpack.docschina.org...
https://github.com/webpack-co...
https://github.com/jantimon/h...

參考的其餘教程:

https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
http://www.cnblogs.com/anani/...
https://blog.csdn.net/bubblin...

來源:http://www.javashuo.com/article/p-srdlxujf-cg.html

相關文章
相關標籤/搜索