webpack开发环境与生产环境分离

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

虽然,以上我们将生产环境和开发环境做了略微区分,但是,请注意,我们还是会遵循不重复原则(Don’t repeat yourself - DRY),保留一个“通用”配置。为了将这些配置合并在一起,我们将使用一个名为 webpack-merge 的工具。通过“通用”配置,我们不必在环境特定(environment-specific)的配置中重复代码。

注:示例的完整代码请参考《Webpack整合实例及优化

安装

推荐使用项目局部安装:在 package.json 中添加如下配置,并进行安装

“webpack-merge”: “^4.1.1”,

配置文件分离

这里写图片描述

webpack.common.js

const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: {
        app: "./js/requireAddDiv.js"
    },
    module: {
        rules: [
            {
                test: /\.(jsx|js)$/,
                use: {
                    loader: "babel-loader?cacheDirectory=true", // 使用cache提升编译速度
                    options: {
                        presets: ["env", "react"],
                        plugins: ["transform-runtime"]// 避免重复引入
                    }
                },
                exclude: /node_modules/
            },
            {// 分离 css
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            },
            {
                test: /\.html$/,
                use: "html-loader"
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(["dist"]),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "index.temp.html")
        })
    ]
};

webpack.dev.js

const merge = require("webpack-merge");
const common = require("./webpack.common");
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = merge(common, {
    devtool: "eval-source-map", // 仅在开发过程中使用
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.[hash].js"
    },
    devServer: {
        contentBase: "./",
        historyApiFallback: true,
        inline: true
        // hot: true // hot module replacement. Depends on HotModuleReplacementPlugin
    },
    module: {
        rules: [
            {// 处理图片,会在 output 目录中生成图片文件,js 中需要使用 require("*.jpg")先行引入才可以,同样 html 中通过 background-image 设置的图片不可以,但 css 中通过 background-image 设置的图片可以
                test: /\.(jpg|png)$/,
                use: {
                    loader: "file-loader",
                    options: {
                        outputPath: "images/", // 这里的 images 貌似没什么作用,但不写不行,可以是任意的一个或多个字符
                        name: "[name].[hash:8].[ext]", // 8表示截取 hash 的长度
                        useRelativePath: true// 这个必须与 outputPath 结合使用才可以处理 css 中的引入的图片
                    }
                }
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin("css/styles-[hash].css") // 可以单独设置css的路径
        // new webpack.NamedModulesPlugin(), // 以便更容易查看要修补(patch)的依赖
        // new webpack.HotModuleReplacementPlugin() // 使用 hot 导致页面不能自动刷新?
    ]
});

webpack.prod.js

const merge = require("webpack-merge");
const common = require("./webpack.common");
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = merge(common, {
    devtool: "source-map",//生产环境也可以设置,有点儿影响性能,但方便调试
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
        rules: [
            {// 处理图片,会在 output 目录中生成图片文件,js 中需要使用 require("*.jpg")先行引入才可以,同样 html 中通过 background-image 设置的图片不可以,但 css 中通过 background-image 设置的图片可以
                test: /\.(jpg|png)$/,
                use: {
                    loader: "file-loader",
                    options: {
                        outputPath: "images/", // 这里的 images 貌似没什么作用,但不写不行,可以是任意的一个或多个字符
                        name: "[name].[ext]",
                        useRelativePath: true// 这个必须与 outputPath 结合使用才可以处理 css 中的引入的图片
                    }
                }
            }
        ]
    },
    plugins: [
        new webpack.BannerPlugin("版权所有,盗版必究!"),
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("production")
            }
        }),
        // new webpack.optimize.OccurrenceOrderPlugin(), // 现在是默认启用,不再需要手动启动
        new webpack.optimize.UglifyJsPlugin({
            output: {
                comments: false// remove all comments
            },
            compress: {
                warnings: false
            },
            sourceMap: true // 如果你在压缩代码时启用了 source map,或者想要让 uglifyjs 的警告能够对应到正确的代码行,你需要将 UglifyJsPlugin 的 sourceMap 设为 true。
        }),
        new ExtractTextPlugin("css/styles.css") // 可以单独设置css的路径
    ]
});

package.json

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "This is just a test",
  "main": "dist/bundle.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --open --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
  "keywords": [
    "webpack",
    "dev-server"
  ],
  "author": "slHuang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.8.1",
    "webpack-dev-server": "^2.9.4",
    "webpack-merge": "^4.1.1",
    "style-loader": "^0.19.0",
    "css-loader": "^0.28.7",
    "postcss-loader": "^2.0.8",
    "autoprefixer": "^7.1.6",
    "babel-core": "^6.26.0",
    "babel-cli": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-react": "^6.24.1",
    "babel-preset-env": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "clean-webpack-plugin": "^0.1.17",
    "html-loader": "^0.5.1",
    "file-loader": "^1.1.5",
    "eslint": "^4.11.0"
  },
  "dependencies": {
    "babel-runtime": "^6.26.0"
  }
}

运行 start 为开发环境,
运行 build 为生产环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值