web-dev-qa-db-ja.com

DefinePluginを介してWebpackを使用してNODE_ENV値を渡す

webpackを介してDefinePluginを使用して_NODE_ENV_値をコードに挿入しようとしています。私は多かれ少なかれ 同一の質問 を確認しましたが、それでも機能しません。

具体的には、これが私の設定です。

_package.json_内:

_"scripts": {
    "build": "rimraf dist && cross-env NODE_ENV=production webpack",
    "dev": "cross-env NODE_ENV=development && node webpack-dev-server.js"
},
_

_webpack.config.js_内:

_"use strict";

/* requiring the modules */
const webpack = require("webpack");
const path = require("path");

/* defining the source and distribution paths */
const DIST_DIR = path.resolve(__dirname, "dist");
const SRC_DIR = path.resolve(__dirname, "src");

const DEVELOPMENT = process.env.NODE_ENV === "development";
const PRODUCTION = process.env.NODE_ENV === "production";
// const PRODUCTION = !!process.argv.find((element) => element === '--production');
// const DEVELOPMENT = !!process.argv.find((element) => element === '--development');


/* defining the entries*/
const productionEntries = {
    home: SRC_DIR + "/_home.js",
    about: SRC_DIR + "/_about.js",
};
const developmentEntries = Object.assign({}, productionEntries, {webpackDevServer: ["webpack/hot/dev-server", "webpack-dev-server/client?http://localhost:8080"]});
const entries = PRODUCTION ? productionEntries : developmentEntries;


/* defining the output */
const output = {
    filename: "[name].js",
    path: DIST_DIR,
    publicPath: "/dist/",
    pathinfo: true,
    library: "MyLibraryName"
};


/* defining the plugins */
const plugins = PRODUCTION
    ? [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.optimize.AggressiveMergingPlugin(),
        new webpack.optimize.UglifyJsPlugin({comments: false}),
    ]
    :  [
        new webpack.HotModuleReplacementPlugin(),
    ];

plugins.Push(
    new webpack.optimize.CommonsChunkPlugin({name: "vendor.bundle", minChunks: 2}),
    new webpack.DefinePlugin({
        PRODUCTION: PRODUCTION,
        DEVELOPMENT: DEVELOPMENT,
    })
);


/* defining the modules -> rules -> loaders */
const modules = {
    rules:
        [
            {
                test: /\.(js|jsx)$/,
                include: SRC_DIR,
                exclude: /node_modules/,
                loader: "babel-loader",
                options:
                    {
                        presets: ["react", ["es2015", {modules: false}], "stage-2"]
                    }
            }
        ]
};



/* building the webpack config object */
const config = {
    entry: entries,
    output: output,
    module: modules,
    plugins: plugins,
    devtool: "source-map",
    target: "web",
    stats: "verbose"
};

/* exporting the webpack config */
module.exports = config;
_

そして最後に、__about.js_には次のようになります。

_// output after using: npm run dev
console.log(process.env.NODE_ENV); // prints undefined
console.log(PRODUCTION); // prints false
console.log(DEVELOPMENT); // prints false

if (module.hot) {
    module.hot.accept();
}
_

問題

  • _npm run dev_が正常に実行される(つまり、サーバーが起動し、プラグインとエントリが適切に選択される)ため、console.log(DEVELOPMENT)の出力がfalseである理由、およびその理由がわかりませんconsole.log(process.env.NODE_ENV)undefinedを出力します。
  • _webpack.config.js_内で実行される条件チェックでは、_NODE_ENV_値が適切に選択されます。そうでない場合、プラグイン、エントリ、および開発サーバーは機能しません。ただし、DefinePluginを使用してその値を__about.js_に渡すことはできません。
  • 私もEnvironmentPluginを試しました、同じ結果。

私の質問:あなたは私を助けてくれますか理解しますどこが壊れているのですか?


編集1:

私は何も改善せずに以下を試しました:

_new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(PRODUCTION),
    DEVELOPMENT: JSON.stringify(DEVELOPMENT)
})
_

_node.js_で_Windows 10_を実行しています。


編集2:

試した:

_const DEVELOPMENT = process.env.NODE_ENV === "development";
const PRODUCTION = process.env.NODE_ENV === "production";

// with this inside plugins:
new webpack.DefinePlugin({
    "process.env.PRODUCTION": JSON.stringify(PRODUCTION),
    "process.env.DEVELOPMENT": JSON.stringify(DEVELOPMENT)
})
_

および(_npm run dev_を使用して)次の出力を取得します。

_console.log(process.env.PRODUCTION); // false
console.log(process.env.DEVELOPMENT); // false
console.log(process.env.NODE_ENV); // undefined
console.log(PRODUCTION); // Uncaught ReferenceError: PRODUCTION is not defined
console.log(DEVELOPMENT); // Uncaught ReferenceError: DEVELOPMENT is not defined
_

残念ながら改善はありません。


編集3:

私のdevDependenciesは:

_"devDependencies": {
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-2": "^6.18.0",
    "cross-env": "^3.1.4",
    "rimraf": "^2.5.4",
    "webpack": "^2.2.0-rc.4",
    "webpack-dev-server": "^2.2.0-rc.0"
}
_

編集4:(解決済み)

@Cleitonが問題を発見しました。これは、npmスクリプトが_cross-env_を使用してどのように構築されるかと関係がありました。以下の完全な回答を参照してください。

13
Mihai

問題は、cross-envを間違った方法で使用しているためです。コンテキストの環境変数のみを変更するため、 '&&'を使用してwebpackを実行すると、webpackはすでに存在せず、webpackには何も表示されません。

だからあなたは書く必要があります

"scripts": {
    "build": "rimraf dist && cross-env NODE_ENV=production webpack",
    "dev": "cross-env NODE_ENV=development node webpack-dev-server.js"
},

「ビルド」スクリプトを正しく書いたことに注意してください。

もう1つの質問は、コードベース内で "process.env.PRODUCTION"への参照を行う場合は、次のように記述する必要があることです。

   new webpack.DefinePlugin({
        "process.env.PRODUCTION": JSON.stringify(PRODUCTION),
        "proccess.env.DEVELOPMENT": JSON.stringify(DEVELOPMENT),
    });
15
Cleiton

DefinePluginは文字列を想定しているため、渡される値をJSON.stringify()にする必要があります。

new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(PRODUCTION),
    DEVELOPMENT: JSON.stringify(DEVELOPMENT)
})
2
Soviut