<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                我們在日常的前端開發工作中,一般都會有兩套構建環境:一套開發時使用,構建結果用于本地開發調試,不進行代碼壓縮,打印 debug 信息,包含 sourcemap 文件;另外一套構建后的結果是直接應用于線上的,即代碼都是壓縮后,運行時不打印 debug 信息,靜態文件不包括 sourcemap 的。有的時候可能還需要多一套測試環境,在運行時直接進行請求 mock 等工作。 webpack 4.x 版本引入了 mode 的概念,在運行 webpack 時需要指定使用 production 或 development 兩個 mode 其中一個,這個功能也就是我們所需要的運行兩套構建環境的能力。 當你指定使用 production mode 時,默認會啟用各種性能優化的功能,包括構建結果優化以及 webpack 運行性能優化,而如果是 development mode 的話,則會開啟 debug 工具,運行時打印詳細的錯誤信息,以及更加快速的增量編譯構建。關于這兩個 mode 的更詳細區別,可以查閱 webpack 作者的這篇文章:[webpack 4: mode and optimization](https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a)。 雖然 webpack 的 mode 參數已經給我們帶來了一些很方便的環境差異化配置,但是針對一些項目情況,例如使用 css-loader 或者 url-loader 等,不同環境傳入 loader 的配置也不一樣,而 mode 并沒有幫助我們做這些事情,因此有些配置還是需要手動區分環境后來進行調整。 ## 在配置文件中區分 mode 之前我們的配置文件都是直接對外暴露一個 JS 對象,這種方式暫時沒有辦法獲取到 webpack 的 mode 參數,我們需要更換一種方式來處理配置。根據官方的文檔[多種配置類型](https://doc.webpack-china.org/configuration/configuration-types/),配置文件可以對外暴露一個函數,因此我們可以這樣做: ``` module.exports = (env, argv) => ({ // ... 其他配置 optimization: { minimize: false, // 使用 argv 來獲取 mode 參數的值 minimizer: argv.mode === 'production' ? [ new UglifyJsPlugin({ /* 你自己的配置 */ }), // 僅在我們要自定義壓縮配置時才需要這么做 // mode 為 production 時 webpack 會默認使用壓縮 JS 的 plugin ] : [], }, }) ``` 這樣獲取 mode 之后,我們就能夠區分不同的構建環境,然后根據不同環境再對特殊的 loader 或 plugin 做額外的配置就可以了。 以上是 webpack 4.x 的做法,由于有了 mode 參數,區分環境變得簡單了。不過在當前業界,估計還是使用 webpack 3.x 版本的居多,所以這里也簡單介紹一下 3.x 如何區分環境。 webpack 的運行時環境是 Node.js,我們可以通過 Node.js 提供的機制給要運行的 webpack 程序傳遞環境變量,來控制不同環境下的構建行為。例如,我們在 npm 中的 `scripts` 字段添加一個用于生產環境的構建命令: ``` { "scripts": { "build": "NODE_ENV=production webpack", "develop": "NODE_ENV=development webpack-dev-server" } } ``` 然后在 `webpack.config.js` 文件中可以通過 `process.env.NODE_ENV` 來獲取命令傳入的環境變量: ``` const config = { // ... webpack 配置 } if (process.env.NODE_ENV === 'production') { // 生產環境需要做的事情,如使用代碼壓縮插件等 config.plugins.push(new UglifyJsPlugin()) } module.exports = config ``` ## 運行時的環境變量 我們使用 webpack 時傳遞的 mode 參數,是可以在我們的應用代碼運行時,通過 `process.env.NODE_ENV` 這個變量獲取的。這樣方便我們在運行時判斷當前執行的構建環境,使用最多的場景莫過于控制是否打印 debug 信息。 下面這個簡單的例子,在應用開發的代碼中實現一個簡單的 console 打印封裝: ``` export default function log(...args) { if (process.env.NODE_ENV === 'development' && console && console.log) { console.log.apply(console, args) } } ``` 同樣,以上是 webpack 4.x 的做法,下面簡單介紹一下 3.x 版本應該如何實現。這里需要用到 [DefinePlugin](https://doc.webpack-china.org/plugins/define-plugin) 插件,它可以幫助我們在構建時給運行時定義變量,那么我們只要在前面 webpack 3.x 版本區分構建環境的例子的基礎上,再使用 DefinePlugin 添加環境變量即可影響到運行時的代碼。 在 webpack 的配置中添加 DefinePlugin 插件: ``` module.exports = { // ... // webpack 的配置 plugins: [ new webpack.DefinePlugin({ // webpack 3.x 的 process.env.NODE_ENV 是通過手動在命令行中指定 NODE_ENV=... 的方式來傳遞的 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }), ], } ``` ## 常見的環境差異配置 前面提及的使用環境變量的方式可以讓我們在不同的構建環境中完成不同的構建需求,這里列舉一下常見的 webpack 構建差異配置: * 生產環境可能需要分離 CSS 成單獨的文件,以便多個頁面共享同一個 CSS 文件 * 生產環境需要壓縮 HTML/CSS/JS 代碼 * 生產環境需要壓縮圖片 * 開發環境需要生成 sourcemap 文件 * 開發環境需要打印 debug 信息 * 開發環境需要 live reload 或者 hot reload 的功能 以上是常見的構建環境需求差異,可能更加復雜的項目中會有更多的構建需求(如劃分靜態域名等),但是我們都可以通過判斷環境變量來實現這些有環境差異的構建需求。 webpack 4.x 的 mode 已經提供了上述差異配置的大部分功能,mode 為 production 時默認使用 JS 代碼壓縮,而 mode 為 development 時默認啟用 hot reload,等等。這樣讓我們的配置更為簡潔,我們只需要針對特別使用的 loader 和 plugin 做區分配置就可以了。 webpack 3.x 版本還是只能自己動手修改配置來滿足大部分環境差異需求,所以如果你要開始一個新的項目,建議直接使用 webpack 4.x 版本。 ## 拆分配置 前面我們列出了幾個環境差異配置,可能這些構建需求就已經有點多了,會讓整個 webpack 的配置變得復雜,尤其是有著大量環境變量判斷的配置。我們可以把 webpack 的配置按照不同的環境拆分成多個文件,運行時直接根據環境變量加載對應的配置即可。基本的劃分如下: * webpack.base.js:基礎部分,即多個文件中共享的配置 * webpack.development.js:開發環境使用的配置 * webpack.production.js:生產環境使用的配置 * webpack.test.js:測試環境使用的配置 一些復雜的項目可能會有更多配置。這里介紹一下如何處理這樣的配置拆分。 首先我們要明白,對于 webpack 的配置,其實是對外暴露一個 JS 對象,所以對于這個對象,我們都可以用 JS 代碼來修改它,例如: ``` const config = { // ... webpack 配置 } // 我們可以修改這個 config 來調整配置,例如添加一個新的插件 config.plugins.push(new YourPlugin()); module.exports = config; ``` 當然,如果是對外暴露一個 JS 函數的話,像本小節第一個例子那樣,那么修改配置就更加容易了,這里不再舉例說明。 因此,只要有一個工具能比較智能地合并多個配置對象,我們就可以很輕松地拆分 webpack 配置,然后通過判斷環境變量,使用工具將對應環境的多個配置對象整合后提供給 webpack 使用。這個工具就是 [webpack-merge](https://github.com/survivejs/webpack-merge)。 我們的 webpack 配置基礎部分,即 webpack.base.js 應該大致是這樣的: ``` module.exports = { entry: '...', output: { // ... }, resolve: { // ... }, module: { // 這里是一個簡單的例子,后面介紹 API 時會用到 rules: [ { test: /\.js$/, use: ['babel'], }, ], // ... }, plugins: [ // ... ], } ``` 然后 webpack.development.js 需要添加 loader 或 plugin,就可以使用 webpack-merge 的 API,例如: ``` const { smart } = require('webpack-merge') const webpack = require('webpack') const base = require('./webpack.base.js') module.exports = smart(base, { module: { rules: [ // 用 smart API,當這里的匹配規則相同且 use 值都是數組時,smart 會識別后處理 // 和上述 base 配置合并后,這里會是 { test: /\.js$/, use: ['babel', 'coffee'] } // 如果這里 use 的值用的是字符串或者對象的話,那么會替換掉原本的規則 use 的值 { test: /\.js$/, use: ['coffee'], }, // ... ], }, plugins: [ // plugins 這里的數組會和 base 中的 plugins 數組進行合并 new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }), ], }) ``` 可見 webpack-merge 提供的 `smart` 方法,可以幫助我們更加輕松地處理 loader 配置的合并。webpack-merge 還有其他 API 可以用于自定義合并行為,這里就不詳細介紹了,需要深入了解的同學可以查閱官方文檔 [webpack-merge](https://github.com/survivejs/webpack-merge)。 ## 小結 本小節介紹了 webpack 4.x 和 3.x 如何在配置文件中區分環境來應用不同的配置選項(4.x 使用 mode 參數,3.x 使用 Node.js 的 `process.env.NODE_ENV`),如何在應用代碼運行時攜帶當前構建環境的相關信息,以及如何利用 [webpack-merge](https://github.com/survivejs/webpack-merge) 這個工具來更好地維護不同構建環境中對應的構建需求配置。 ## 例子 本小節提及的一些簡單的 Demo 可以在 [webpack-examples](https://github.com/teabyii/webpack-examples) 找到。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看