bugfix> javascript > 投稿

次のようなモジュールがあります。

let Info = {};
Info.VALUE_ONE = 123;
Info.VALUE_TWO = 456;
Info.VALUE_THREE = 789;
module.exports = Info;

このモジュールがコンパイルされた後、コードから完全に消えて、値123、456、および789が適切な場所にインライン化されるようにしたい-Webpackでこれを行うにはどうすればよいですか?

回答 2 件
  • 1つの解決策は、string-replace-loaderを使用して Info.<key> をインライン化することです。   <value> へ 。次に、モジュール自体を削除するには、2つのオプションがあります。

    オプション1:commonjs構文を保持し、null-loaderを使用してモジュールを空のオブジェクトに変換します。この方法の注意点は、webpackが require を安全に想定しているため、モジュールへの参照を削除する方法がないことです。  ステートメント自体が副作用を引き起こす可能性があります1

    オプション2:es6インポートおよびエクスポートの使用を開始し、webpackのmodule-concatenation-pluginを使用します。これにより、info.jsがコンシューマと同じスコープに配置され、ミニファイヤがコードを削除できるようになります( Info への参照がないため)  オブジェクト)。また、esmを使用して npx webpack -r esm 経由でwebpack構成ファイルをロードする必要があります。

    次のディレクトリ構造が与えられた場合:

    - index.js
    - info.js
    - webpack.config.js
    
    

    このコードは、あなたが探しているものを提供するはずです(私はそれらを折りたたみ可能にするためにコードスニペット構文を使用しました-コードは実行できません)

    オプション1のコード

       // info.js
        module.exports {
          VALUE_ONE: 123,
          VALUE_TWO: 456,
          VALUE_THREE: 789,
        }
    
        // index.js
        const Info = require('./info')
        console.log(Info.VALUE_ONE)
    
        // webpack.config.js
        const Info = require('./info')
        const searchAndReplaceInfo = createSearchAndReplaceInfo(Info)
        module.exports = {
          mode: 'development',
          entry: './index.js',
          output: {
            filename: 'bundle.js',
            path: __dirname
          },
          module: {
            rules: [
              {
                test: path.resolve(__dirname, 'info.js'),
                use: 'null-loader'
              }, {
                exclude: /\/node_modules\//,
                loader: 'string-replace-loader',
                options: {
                  multiple: searchAndReplaceInfo
                }
              }
            ]
          }
        }
        function createSearchAndReplaceInfo(Info) {
          return Object.keys(Info).map(key => [key, Info[key]]).map(toSearchAndReplace)
        }
        function toSearchAndReplace([key, value]) {
          return {
            search: 'Info.' + key,
            replace: '' + value
          }
        }
    
    


    オプション2のコード

       // info.js
        export default {
          VALUE_ONE: 123,
          VALUE_TWO: 456,
          VALUE_THREE: 789,
        }
    
        // index.js
        import Info from './info'
        console.log(Info.VALUE_ONE)
    
        // webpack.config.js
        import Info from './info'
        import webpack from 'webpack'
        const searchAndReplaceInfo = createSearchAndReplaceInfo(Info)
        export default {
          mode: 'development',
          entry: './index.js',
          output: {
            filename: 'bundle.js',
            path: __dirname
          },
          plugins: [ new webpack.optimize.ModuleConcatenationPlugin() ],
          module: {
            rules: [
              {
                exclude: /\/node_modules\//,
                loader: 'string-replace-loader',
                options: {
                  multiple: searchAndReplaceInfo
                }
              }
            ]
          }
        }
        function createSearchAndReplaceInfo(Info) {
          return Object.keys(Info).map(key => [key, Info[key]]).map(toSearchAndReplace)
        }
        function toSearchAndReplace([key, value]) {
          return {
            search: 'Info.' + key,
            replace: '' + value
          }
        }
    
    


    副作用1

    A "side effect" is defined as code that performs a special behavior when imported, other than exposing one or more exports. An example of this are polyfills, which affect the global scope and usually do not provide an export.

  • webpack.DefinePlugin を使用したいようです 、コンパイル時にグローバル値をインライン化できます。

    webpack.config.js

    plugins: [
      new webpack.DefinePlugin({
        Info: require('./info.js'),
      }),
      //...
    ]
    
    

    例として、ソースコードは次のように変換されます。

    ソース

    let value = null;
    switch (value) {
      case Info.VALUE_ONE:
        //...
      case Info.VALUE_TWO:
        //...
      case Info.VALUE_THREE:
        //...
      default:
        //...
    }
    
    

    出力

    let value = null;
    switch (value) {
      case 123: //...
      case 456: //...
      case 789: //...
      default: //...
    }
    
    

あなたの答え