[ 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"
  }
}

复制代码
相关文章
相关标签/搜索