[ webpack4 ] 配置屬於本身的打包系統教程(最終篇)—— 環境配置篇

GitHub 完整配置文件地址: https://github.com/yhtx1997/webpack4-Instancecss

因爲篇幅過長分三次發佈,建議按順序看html

環境配置篇

主要內容node

  • 開發環境生產環境分離
  • 實時預覽
  • webpack-dev-server 其餘經常使用
  • 代碼複用處理

開發環境和生產環境

到了這一步,該講講開發環境模式和生產環境模式了webpack

  • 開發環境是本身開發時用的,須要有實時編譯功能、模塊熱替換功能(更新文件不用徹底更新頁面)、錯誤提示到具體哪一個文件幾行
  • 生產環境是放到線上給用戶使用的,須要代碼壓縮功能

配置代碼組件化

咱們先把以前配置好的 webpack 配置文件改下名,更名 webpack.common.js ,意思是開發環境和生產環境都須要的,將代碼壓縮之類的挪到生產配置下 以後安裝 webpack-merge ,官方推薦的是爲每一個環境寫單獨的 webpack 文件git

雖然有簡單的方法實現可是依然推薦寫單獨的配置文件,由於在這樣的配置方式你能夠更清楚你本身在作什麼,還可讓你的配置更加個性(自定義)github

安裝 webpack-merge

npm install webpack-merge -D
複製代碼

新建開發環境配置

咱們新建一個 js 文件,命名爲 webpack.dev.js ,添加以下代碼web

const merge = require('webpack-merge');//合併配置
const common = require('./webpack.common.js');//引入公共配置

 module.exports = merge(common, {
    mode: 'development',//聲明是開發環境
     //關於 dev 的配置
 })
複製代碼

新建開發環境配置

咱們新建一個 js 文件,命名爲 webpack.prod.jsnpm

添加以下代碼json

const merge = require('webpack-merge');//合併配置
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');//用來壓縮 js 代碼
const common = require('./webpack.common.js');//引入公共配置

module.exports = merge(common, {
    mode: 'production',//聲明是生產環境
    //關於 prod 的配置
});
複製代碼

開發環境

實時預覽

跟着配置並操做的小夥伴可能發現了,每次修改後都須要手動在命令行輸入命令,而且還要刷新瀏覽器才能看到最新的效果api

那麼如今來解決這兩個問題,方法就是使用 webpack-dev-server

安裝
npm install webpack-dev-server -D
複製代碼
配置
  • 實時預覽
  • 自定義請求代理
  • 自定義 ip 及端口
  • 注:使用 webpack-dev-server 並不會編譯到本地文件,而是放到內存中
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');
const webpack = require('webpack');

 module.exports = merge(common, {
    mode: 'development',
    devServer: {
        contentBase: path.join(__dirname, 'dist'),//預覽的目錄,寫出口目錄的絕對路徑
        host: 'localhost',//默認值 也能夠改成 127.0.0.1 或者其餘
        port: 8080,
        proxy: {
            '/api': 'http://localhost:3000'//請求到 /api/users 如今會被代理到請求 http://localhost:3000/api/users
        }

    }
 })
複製代碼

接下來加入錯誤提示以及將生成 HTML 的代碼從公共配置( webpack.common.js )拿到這裏

由於開發和生產有些許不同,我又不知道怎樣簡單配置,因此開發環境和生產環境我都會放一個生成 HTML 的代碼

生產環境

  • 每次打包都要清理掉舊文件
  • 全部代碼都要進行壓縮
  • 重複的 js 代碼,須要只有一個就好

文件清理

從公共配置( webpack.common.js )將以前文件清理的代碼拿過來放到這裏

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

module.exports = merge(common, {
    mode: 'production',
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: '2048',
            template: './src/index.html',
            minify: true,//HTML 代碼壓縮
            hash: true
        }),
    ],
})
複製代碼

代碼壓縮

先安裝壓縮代碼的插件

npm install uglifyjs-webpack-plugin -D 
npm install optimize-css-assets-webpack-plugin -D 

複製代碼
  • uglifyjs-webpack-plugin 是 js 壓縮插件
  • optimize-css-assets-webpack-plugin 是推薦和
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
複製代碼

複用代碼分離

假設須要使用 jQuery 來輔助開發,我在 a.js b.js 兩個文件都引入了 jQuery ,將 a.js b.js 打包成 a.min.js b.min.js ,這時看他們的體積會比原來大不少,且 a 和 b 的代碼中都包含完整的 jQuery 代碼

爲了解決這種狀況,咱們須要將 jQuery 這種複用的代碼分離到單獨的文件

在將環境設置爲生產環境時默認開啓了不少功能,其中 SplitChunksPlugin 就是用於避免重複依賴的

在咱們不配置時 默認配置是這樣的

optimization: {
    splitChunks: {
      chunks: 'async', 
      minSize: 30000,
      minChunks: 1,
    }
  }

複製代碼
  • chunks: 表示哪些代碼須要優化,有三個可選值:initial(初始塊)、async(按需加載塊)、all(所有塊),默認爲async 改爲 all 支持全部的
  • minSize: 這個文件最少是多少纔去優化,默認爲 30000 實際測試是文件大於 30 kb,在 31kb時開始優化
  • minChunks: 最少引用幾回纔去優化,默認爲1 實際測試爲在只引用一次的狀況不優化,只有大於它才優化
  • 注: 還有其餘屬性我的感受不經常使用就沒寫,瞭解更多能夠看這裏

最終代碼彙總

最終公共配置 webpack.common.js 代碼以下

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: {
        512:'./src/js/512.js',
        1024:'./src/js/1024.js',
        2048:'./src/js/2048.js',
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].css"
        })
    ],
    output: {
        filename: "js/[name].js",
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                  loader: 'babel-loader',
                  options: {
                    presets: ['@babel/preset-env']
                  }
                }
              },
              {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.(csv|tsv)$/,
                use: [
                    'csv-loader'
                ]
            },
            {
                test: /\.xml$/,
                use: [
                    'xml-loader'
                ]
            }
        ]
    },

}
複製代碼

最終開發環境 webpack.dev.js 代碼以下

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = merge(common, {
    mode: 'development',
    plugins: [
        new HtmlWebpackPlugin({
            title: '2048',
            template: './src/index.html',
            minify: false,
            hash: true
        })
    ],
    devtool: 'inline-source-map',
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        host: 'localhost',
        port: 8080,
        proxy: {
            '/api': 'http://localhost:3000'
        }

    }
 })
複製代碼

最終生產環境 webpack.prod.js 代碼以下

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = merge(common, {
    mode: 'production',
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: '2048',
            template: './src/index.html',
            minify: true,
            hash: true
        }),
    ],
    optimization: {
        splitChunks: {
            chunks: 'all'
        },
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true 
            }),
            new OptimizeCSSAssetsPlugin({})
        ],
    }
});
複製代碼

npm 項目配置代碼 package.json 代碼以下

{
  "name": "2048",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --open --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "webpack": "^4.28.3"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.2.3",
    "autoprefixer": "^9.4.3",
    "babel-loader": "^8.0.4",
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^2.1.0",
    "csv-loader": "^3.0.2",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.5.0",
    "node-sass": "^4.11.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "postcss": "^7.0.7",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "uglifyjs-webpack-plugin": "^2.1.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.14",
    "webpack-merge": "^4.1.5",
    "xml-loader": "^1.2.1"
  }
}

複製代碼
相關文章
相關標籤/搜索