Vue+webpack搭建自己的腳手架

米西米西可可發表於2019-03-24

一, 初始化自己的專案

(1). 初始化npm

npm init 
<!--一路回車,會生成package.json檔案-->
複製程式碼

(2). 在根目錄下新建src, build 資料夾,新建index.html作為html模版

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Vue-webpack</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <div id="app"></div>
</body>
</html>
複製程式碼

(3). 安裝依賴

由於webpack4及以後的版本中webpack和webpack-cli是配套的,所以兩個必須同時安裝,webpack-cli設計思路是命令式的幫助配置webpack,免於寫webpack配置檔案,但並未完善,並沒有感覺多快。

npm i webpack webpack-cli -D
複製程式碼

二, 配置webpack

在build目錄下新建一下三個檔案:

webpack.base.config.js
webpack.dev.config.js
webpack.prod.config.js
複製程式碼

分別應用於基礎公用配置編寫,開發環境配置編寫,生產環境配置編寫

(1). webpack.base.config.js配置

const path = require('path')
module.exports = {
    entry: {
        app: '../src/index.js'
    },
    output: {
        // __dirname是node中的一個全域性變數
        path: path.resolve(__dirname, '../dist'),
        filename: '[name].[hash:5].js'
    },
    module: {
        rules: []
    },
    plugins: []
}
複製程式碼

(2). webpack.dev.config.js配置

const merge = require('webpack-merge')
const path = require('path')
const baseConf = require('./webpack.base.config')

// 通過merge合併development和base的配置
module.exports = merge(baseConf, {
    // webpack4中必須指定開發環境,也可以在npm script指令碼中指定
    mode: 'development',
    devtool: 'souce-map',
    devServer: {
        contentBase: path.resolve(__dirname, '../dist'),
        port: 3000
    }
})
複製程式碼

(3). webpack.prod.config.js配置

const merge = require('webpack-merge')

const path = require('path')
const baseConf = require('./webpack.base.config')

module.exports =merge(baseConf, {
    mode: 'production',
    devtool: 'source-map',
    module: {
        rules: []
    },
    plugins: []
})
複製程式碼

(4). 配置基本外掛

npm i webpack clean-webpack-plugin html-webpack-plugin -D
複製程式碼

由於html-webpack-plugin外掛prod和dev環境都用的貸,所以放在base下

const htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
    new htmlWebpackPlugin({
        template: path.resolve(__dirname, '../index.html'),
    })
]
複製程式碼

clean-webpack-plugin外掛放在prod環境下,打包前清除dist目錄下的檔案

const cleanWebpackPlugin = require('clean-webpack-plugin')
 plugins: [
    // 新版本的外掛只接受一個物件配置作為引數
    new cleanWebpackPlugin({
        root: path.resolve(__dirname, '../dist/')
    }),
]
複製程式碼

(5). npm script指令碼配置

"build": "webpack --config build/webpack.prod.config.js",
"dev": "webpack-dev-server --progress --config build/webpack.dev.config.js"
複製程式碼

在src/index.js下寫

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

分別執行

npm run dev 
npm run build
複製程式碼

檢視打包成功與否

三, 配置plugins和loader (1). 配置babel來轉換ES6語法

npm i  @babel/runtime  @babel/core  @babel/plugin-transform-runtime @babel/preset-env  babel-loader -D
複製程式碼

在根目錄下新建.babelrc檔案並配置:

{
    "presets": [
        [
            "@babel/preset-env", {
                "targets": {
                    "browsers": ["> 1%", "last 2 versions"]
                },
                // 用來treeshaking,不要將es6模組轉換為common.js
                "modules": false,
                "useBuiltIns": "usage"
            }
        ]
    ],
}
複製程式碼

在webpack.base.config.js的module下:

        {
            test: /\.js$/,
            exclude: /node_modules/,
            use: [{
                loader: 'babel-loader',
                options: {}
            }]
        }
複製程式碼

現在可以在index.js中寫es6語法

(2). 處理樣式

在這裡我個人比較喜歡原生css + css-module

npm i postcss-loader css-loader style-loader autoprefixer -D
複製程式碼

在webpack.base.config.js的module下:

{
    test: /\.css$/,
    use: [
        {
            loader: 'style-loader'
        },{
            loader: 'css-loader',
            options: {
                /* 是否壓縮 */
                minimize: true,
                /* 啟用 css-modules */
                modules: true,
                /* 定義編譯出來的名稱 */
                localIdentName: '[path][name]_[local]_[hash:base64:5]'
            }
        },
        {
            /* 將css3屬性新增上廠商字首 */
            loader: 'postcss-loader',
            options: {
                ident: 'postcss',
                plugins: [
                    /* 根據.browserlist加 css 各瀏覽器字首 */
                    require('autoprefixer')({
                        browsers: ['last 2 versions'] 
                    })
                ]
            }
        }
    ]
}
複製程式碼

(3). 處理file檔案

// 各種loader 按自己需求配置就行
npm i file-loader url-loader img-loader -D
複製程式碼

(4). .vue檔案

.vue的單檔案寫法給了開發很大的便利,採用vue-loader編譯template模版編。其中vue-loader 和 vue-template-compiler必須一起安裝,我們也可以用vue-style-loader替換style-loader將樣式插入模版中

npm i vue-loader  vue-style-loader vue-template-compiler -D
npm i vue -S
複製程式碼

在webpack.base.config.js的module下:

const vueLoaderPlugin = require('vue-loader/lib/plugin')
module: {
    rules: [ 
        {
            test: /.vue$/,
            loader: 'vue-loader'
        }
    ]
}
plugins: [
    new vueLoaderPlugin()
]
複製程式碼

vueLoaderPlugin外掛是必須的,它可以將之前定義過的module規則(比如說處理es6語法等等)應用到.vue相應的程式碼塊中。 現在可以在src檔案下寫vue程式碼了:

// index.js
import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    render: h => h(App)
})
// App.vue 利用css-module
<template>
    <div :class="$style.page">
        <div :class="$style.left">back</div>
        <div :class="$style.right">for</div>
    </div>
</template>
<script>
export default {
}
</script>
<style module>
    .div {
        font-size: 15px;
        cursor: pointer;
        border: 1px solid black;
        height: 30px;
        line-height: 30px;
        vertical-align: middle;
        border-radius: 5px;
        margin:0 2px;
        text-align: center;
        box-shadow: 1px 1px gray
    }
    .page {
        /* composes: div; */
        display: flex;
    }
    .left {
        composes: div;
        width: 45px;
    }
    .right {
        composes: div;
        width: 45px;
    }
</style>
複製程式碼

三, 優化 (1). 配置resolve

webpack.base.config.js下:

resolve: {
    alias:{
        'vue$': 'vue/dist/vue.esm.js',
        '@': path.resolve(__dirname, '../src'),
    },
    extensions: ['*', '.js', '.json', '.vue'],
},
複製程式碼

(2) 開啟熱更新

webpack4配置熱更新較為簡單

1) 設定devServer.hot = true
2) 開啟 webpack.HotModuleReplacementPlugin外掛
複製程式碼

vue-style-loader內建了style-loader,css熱更新開箱即用。js熱更新需要在入口js檔案面加入一句判斷:

if (module.hot) {
    module.hot.accept();
}
複製程式碼

(3) 配置happypack

happyloader將任務分解成多個子程式去併發執行,子進行處理完之後將結果傳送給
主程式。例如因為babel-loader要分析將程式碼轉化成ast,引入響應的polyfill,是一個很耗時的工作。
利用happyloader去處理babel-loader,所有需要經過babel-loader處理的檔案都先
交給了happypack/loader去處理。每通過new HappyPack()例項就是告訴happyPack核心排程器
如何通過一系列Loader去轉換一類檔案,並且可以制定如何為這類轉換器分配子程式
複製程式碼

安裝:

npm i happypack 
複製程式碼

配置:

const happyPack = require('happypack')
const happyThreadPool = happyPack.ThreadPool({size: os.cpus().length})
{
        test: /\.js$/,
        // exclude: /node_modules/,
        use: [{
            loader: 'happypack/loader?id=happybabel'
        }]
},
plugins: [
    new happyPack({
        id: 'happybabel',
        loaders: [{
            loader: 'babel-loader?cacheDirectory=true',
        }],
        verbose: true,
        // 共享程式池
        threadPool: happyThreadPool
    })
]
複製程式碼

(4). 提取runtime 程式碼

webpack4新增的 optimization.runtimeChunk 和 optimization.splitChunks用來替代 webpack3 中 commonsChunkPlugin 進行程式碼分割

optimize: {
    runtimeChunk: {
        name: 'manifest'
    }
},
//剩餘拆分第三方程式碼可以利用 optimization.splitChunks 配置
複製程式碼

(5). 動態連結庫DLL

第三方程式碼 比如react vue vue-router等除了版本更迭,剩下不會有太大變化,所以可以將其放到 dll 動態連結庫中,優化打包速率。

1). build目錄下新建 webpack.dll.config.js 並配置
    const webpack = require('webpack')
    const path = require('path')
    const CleanWebpackPlugin = require("clean-webpack-plugin");

    module.exports = {
        entry: {
            vendors: ['vue']
        },
        output: {
            filename: '[name].[hash:5].dll.js',
            // 存放dll庫
            path: path.resolve(__dirname, "../src/assets/dll"),
            // 動態連結庫全域性變數名稱
            library: "_dll_[name]"
        },
        plugins: [
            new CleanWebpackPlugin({
                root: path.resolve(__dirname, "../src/assets/dll.js")
            }),
            new webpack.DllPlugin({
                //需要和動態連結庫全域性變數名稱相同,因為通過全域性變數名稱找到相對應的第三方庫
                name: '_dll_[name]',
                path: path.resolve(__dirname,'[name].dll.manifest.json')
            })
        ]
    }
2). 在webpack.dev.config.js下
    new webpack.DllReferencePlugin({
        manifest: require('./vendors.dll.manifest.json')
    }),
3) npm scrip中:
    "dll": "webpack --mode production --config build/webpack.dll.config.js"
複製程式碼

先npm run dll 再進行npm run build打包,明顯可以看出打包的程式碼小的多。

(5) 提取css

webpack4利用 mini-css-extract-plugin 外掛

安裝並引用外掛即可

總結:

webpack更新版本太快,webpack5好像出來了,一切以官方文件為準複製程式碼

相關文章