Webpack 学院 #6:拆分开发和生产模式的配置

2025-06-08

Webpack 学院 #6:拆分开发和生产模式的配置

所以从现在开始我们可以管理很多事情,但我们需要将配置分为两部分:

  • 开发部分(针对开发人员)

  • 生产部分(当我们在网络上部署应用程序时)

到目前为止我们只关注产品部分

因此在本文中,我们将把配置分成 3 个文件!

  • webpack 常用配置

  • 产品配置

  • 开发配置

webpack 常用配置

一些属性对于 dev 和 prod 配置文件来说是通用的,因此我们可以创建一个包含这些字段的文件以避免重复代码!

开始之前,我们需要安装一个名为 的包webpack-merge,它会将两个配置文件合并为一个!这样我们就可以将 .merge-common 文件与 .merge-common 文件合并了!

此后,我们创建一个通用配置文件👇

const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const cdn = require("./cdn")

const config = {
    // Webpack start from this entry point
    entry: {
        myApp: [
            "./src/style.css",
            "./src/main.js",
        ],
    },
    // External lib that will not be put in bundle but use from CDN
    externals: {
        lodash: '_',
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: 'Webpack academy title',
            template: './src/index.html',
            inject: 'body',
            cdn,
            minify: {
                removeComments: true,
                collapseWhitespace: false
            }
        }),
        new BundleAnalyzerPlugin({
            openAnalyzer: true,
            analyzerMode: 'server',
        })
    ],
}

module.exports = config
Enter fullscreen mode Exit fullscreen mode

通用配置中,我们需要使用捆绑分析器进行生产和开发模式,我们还需要HTML 插件干净的 webpack

我们还需要使用cdn

我们创建了一个产品配置文件!

产品配置文件

const commonConfig = require("./webpack.config.common")
const merge = require('webpack-merge')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

const config = {
    mode: "production",
    module: {
        rules: [
            {
                // Match file extension
                test: /\.css$/,
                // Order of loader from bottom to up
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ],
            }
        ]
    },
    // This is the output of Webpack
    output: {
        // From current folder + dist folder that will contains all bundle
        path: path.resolve(__dirname, "dist/"),
        filename: "[contenthash:8].js"
    },
    optimization: {
        minimize: true,
    },
    plugins: [
        new MiniCssExtractPlugin({
            // Name output by extract
            filename: "style.css",
        }),
    ],
}

// Merge commonConfig with prod config, priority to prod config
module.exports = merge(commonConfig, {
    ...config,
})
Enter fullscreen mode Exit fullscreen mode

生产模式下,我们需要使用哈希提取 css最小化捆绑代码

生产部分几乎完成了,我们需要重命名cdn文件,cdn.prod.js因为我们将在生产和开发模式下为 cdn 使用两个单独的文件!

我们需要编辑script file👇

"build": "cross-env --env.NODE_ENV=prod webpack --config webpack.config.prod.js"
Enter fullscreen mode Exit fullscreen mode

从现在起,生产部分已经完成

一切进展顺利!这是一个很好的开始,让我们继续推进生产部分!

开发配置文件

让我们开始创造吧cdn.dev

不同的是prod cdn,我们不会使用minify库的版本!我们只会使用经典版本

module.exports = {
    js: [
        "https://unpkg.com/lodash@4.17.15/lodash.js",
    ],
}
Enter fullscreen mode Exit fullscreen mode

在此之后,我们需要安装webpack-dev-server,它用于像开发人员的开发服务器一样处理开发服务!

并创建开发配置👇

const path = require("path")
const commonConfig = require("./webpack.config.common")
const merge = require('webpack-merge')

const config = {
    mode: "development",
    devServer: {
        // Show info about dev server
        noInfo: false,
        // Port of dev server
        port: 8080,
        // Asking the server to fallback to index.html in the event that a requested resource cannot be found, need to vue router
        historyApiFallback: true,
        // Allows https in dev server
        // Use this https://stackoverflow.com/questions/35531347/localhost-blocked-on-chrome-with-privacy-error for allow https in localhost directly on chrome
        https: true,
    },
    // This is the output of Webpack
    output: {
        // From current folder + dist folder that will contains all bundle
        path: path.resolve(__dirname, "dist/"),
        filename: "bundle.dev.js"
    },
    module: {
        rules: [
            {
                // Match file extension
                test: /\.css$/,
                // Use multiple loader
                // Order => from bottom to top
                use: [
                    'style-loader',
                    'css-loader'
                ],
            }
        ]
    }
}


// Merge commonConfig with prod config, priority to prod config
module.exports = merge(commonConfig, {
    ...config,
})
Enter fullscreen mode Exit fullscreen mode

因为css part我们需要使用,style-loader因为我们需要在 DOM 中注入样式!

我们使用一些属性,例如porthttps等等......(查看上面的评论)

但有一件事非常有趣,我应该向你解释一下🔥

historyApiFallback:

当您使用 Vuejs 或 React 之类的框架时,您将在两件事之间进行选择 -> 在前端或后端使用路由器。

例如,如果您使用 vuejs,则需要使用VueRouter(在前端处理应用程序的路由)。

您需要通知托管您的应用程序的当前服务器(在我的情况下是 webpack 服务器),您通过前端处理路由而不是通过服务器(后端)处理路由。

但为什么 ?

例如,如果您使用路由器前端,您将尝试此 URL 👇

https://toto.com/test
Enter fullscreen mode Exit fullscreen mode

服务器将尝试从服务器文件中访问/test文件,但由于该文件不存在(因为你通过前端处理路由),因此不会得到任何结果。你将得到一个404

为了避免这种情况,我们需要告诉服务器 ->If you have a 404, access to the root file (main file) and not looking for /test file

此后,您可以输入任何 URL,您的项目就会运行!

因此,此选项historyApiFallback只是为了防止这种情况发生,如果您在前面部分使用路由器,则应该放true!否则放false

我们快完成了💪

创建命令以在开发模式下运行我们的应用程序

"dev": "cross-env --env.NODE_ENV=dev webpack serve --hot --config webpack.config.dev.js",
Enter fullscreen mode Exit fullscreen mode

webpack serve --hot:以热重载模式运行 webpack 服务器的命令(当文件发生更改时,我们会自动重新加载项目)

源图

我们不会详细介绍这一点,如果你想查看这个网址 -> https://blog.teamtreehouse.com/introduction-source-maps

简而言之,在开发模式下,我们需要调试一些文件,如果我们不使用源映射,我们将会有一些有点奇怪的文件,例如我们的main.js👇

lodash__WEBPACK_IMPORTED_MODULE_1___default().cloneDeep({})
console.log(_three__WEBPACK_IMPORTED_MODULE_0__.three)

document.getElementById("button").addEventListener("click", function() {
    jsonObjectImport().then(jsonObject => console.log(jsonObject.default))
})
Enter fullscreen mode Exit fullscreen mode

在这里这不是问题,但是对于大文件,我们在调试时可能会遇到一些麻烦!

我们的英雄也是source map!🦸‍♂️

devtool: 'eval-cheap-source-map',
Enter fullscreen mode Exit fullscreen mode

(关于源映射,您有很多选择,对我来说,在开发中最好使用“eval-cheap-source-map”),请查看此 URL 以获取更多信息:https://webpack.js.org/configuration/devtool/

当你想要调试时main.js,你会看到另一个文件,就像main.js?56d7这样,这就是我们需要调试的文件!打开它,👇

import { three } from './three'
import _ from 'lodash'
const jsonObjectImport = async () => import(/* webpackChunkName: "myChunkName" */ "./big-object.json")

_.cloneDeep({})
console.log(three)

document.getElementById("button").addEventListener("click", function() {
    jsonObjectImport().then(jsonObject => console.log(jsonObject.default))
})
Enter fullscreen mode Exit fullscreen mode

这就像我们的原始main.js文件一样!

总结一下源图:

当我们使用 Webpack 捆绑我们的代码时,它会将我们的原始文件编译成另一个特殊文件(可能很奇怪),所以如果我们想要调试我们的代码,我们将拥有这个与原始文件代码不同的特殊文件。

为了解决这个问题,我们可以使用源映射来跟踪原始文件(每个原始文件都有一个特殊的哈希值)。这样,如果我们需要调试代码,就可以像找到原始文件一样找到该文件!

做得好!💪🔥

我们成功了!我们成功将原始配置拆分成两部分!

我们即将完成 webpack 学院的课程!

我希望你喜欢这个,你可以在这个提交中查看源代码

📝 注意:如果我们需要在两种情况下检查包大小,我们会在 prod 和 dev 模式下为包分析器创建另外两个命令


我希望你喜欢这篇文章!

🎁 如果您在TwitterUnderrated skills in javascript, make the difference上关注我并给我点赞,即可免费获得我的新书😁

或者在这里获取

🎁我的新闻通讯

☕️ 你可以支持我的作品🙏

🏃‍♂️ 你可以关注我 👇

🕊 推特:https://twitter.com/code__oz

👨‍💻 Github:https://github.com/Code-Oz

你也可以标记🔖这篇文章!

鏂囩珷鏉ユ簮锛�https://dev.to/codeoz/webpack-academy-6-split-your-config-for-dev-prod-mode-2le7
PREV
学习 Sass
NEXT
Vue 学院 #6:异步更新队列