React / NPM не подчиняется переменным env во время сборки - PullRequest
1 голос
/ 13 марта 2019

Я устанавливаю среду в файле констант примерно так

const ENVIRONMENT = process.env.NODE_ENV;
const ENV_VARIABLES = {
  production: {
    API_URL: 'https://prod.myapi.com',
  },
  development: {
    API_URL: 'https://dev.myapi.com',
  },
  stage: {
    API_URL: 'https://stage.myapi.com/',

  }
};

export const API_URL = ENV_VARIABLES[ENVIRONMENT].API_URL;

В моем файле package.json содержатся следующие команды

"scripts": {
    "build": "cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
    "stage": "cross-env NODE_ENV=stage webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
    "start": "cross-env NODE_ENV=development node server",
  },

npm run build использует production среда как ожидается

npm start использует среду development как ожидается

npm run stage использует среду production, когда она должна использовать API_URL сцены.

РЕДАКТИРОВАТЬ

Я обновил stage в package.json до следующих

"stage": "cross-env NODE_ENV=stage webpack --config internals/webpack/webpack.stage.babel.js --color -p --progress --hide-modules --display-optimization-bailout",

и internals/webpack/webpack.stage.babel.js следующим образом (длинное предупреждение о файле).Единственная разница между этим и webpack.stage.babel.js состоит в mode:none, это настройка на mode:production в webpack.production.babel.js

// Important modules this config uses
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
// const OfflinePlugin = require('offline-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = require('./webpack.base.babel')({
  mode: 'none',

  // In production, we skip all hot-reloading stuff
  entry: [
    require.resolve('react-app-polyfill/ie11'),
    path.join(process.cwd(), 'app/app.js')
  ],

  // Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].chunk.js'
  },

  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          warnings: false,
          compress: {
            comparisons: false
          },
          parse: {},
          mangle: true,
          output: {
            comments: false,
            ascii_only: true
          }
        },
        parallel: true,
        cache: true,
        sourceMap: true
      })
    ],
    sideEffects: true,
    concatenateModules: true,
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      name: true,
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all'
        },
        main: {
          chunks: 'all',
          minChunks: 2,
          reuseExistingChunk: true,
          enforce: true
        }
      }
    },
    runtimeChunk: true
  },

  plugins: [
    // Minify and optimize the index.html
    new HtmlWebpackPlugin({
      template: 'app/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      },
      inject: true
    }),

    // Put it in the end to capture all the HtmlWebpackPlugin's
    // assets manipulations and do leak its manipulations to HtmlWebpackPlugin
    /*new OfflinePlugin({
      relativePaths: false,
      publicPath: '/',
      appShell: '/',

      // No need to cache .htaccess. See http://mxs.is/googmp,
      // this is applied before any match in `caches` section
      excludes: ['.htaccess'],

      caches: {
        main: [':rest:'],

        // All chunks marked as `additional`, loaded after main section
        // and do not prevent SW to install. Change to `optional` if
        // do not want them to be preloaded at all (cached only when first loaded)
        additional: ['*.chunk.js']
      },

      // Removes warning for about `additional` section usage
      safeToUseOptionalCaches: true
    }),*/

    new CompressionPlugin({
      algorithm: 'gzip',
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
    }),

    new WebpackPwaManifest({
      name: 'React Boilerplate',
      short_name: 'React BP',
      description: 'My React Boilerplate-based project!',
      background_color: '#fafafa',
      theme_color: '#b1624d',
      inject: true,
      ios: true,
      icons: [
        {
          src: path.resolve('app/images/icon-512x512.png'),
          sizes: [72, 96, 128, 144, 192, 384, 512]
        },
        {
          src: path.resolve('app/images/icon-512x512.png'),
          sizes: [120, 152, 167, 180],
          ios: true
        }
      ]
    }),

    new HashedModuleIdsPlugin({
      hashFunction: 'sha256',
      hashDigest: 'hex',
      hashDigestLength: 20
    })
  ],

  performance: {
    assetFilter: assetFilename =>
      !/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)
  }
});

1 Ответ

1 голос
/ 01 апреля 2019

Не могу реально увидеть, где вы используете API_URL, но я предполагаю, что вы просто используете его прямо в коде клиента.В любом случае, я уверен, что проблема в аргументе -p, который вы передаете в веб-пакет.Вы должны прочитать о том, что означает этот аргумент, прежде чем применять его.

И -p аргумент является ярлыком для --define process.env.NODE_ENV="production" аргумента, который передает NODE_ENV=production во время выполнения сборки через DefinePlugin.

Кстати, я не уверен на 100%, но я считаю, что веб-пакет не передает переменную NODE_ENV env автоматически во время выполнения компиляции, поэтому, если вы уже это не делаете (потому что яя не вижу его в предоставленном вами конфиге) Я считаю, что вы должны передать NODE_ENV во время выполнения компиляции следующим образом:

new webpack.DefinePlugin({
  // it's important to use JSON.stringify here in order to escape quotes
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})

Или используя аргумент CLI:

--define process.env.NODE_ENV="staging"
...