8

不知道发生了什么,当我进行产品构建(“cross-env NODE_ENV=production API_V=production npm run build”)时,我从 react-player 收到此错误:

./node_modules/react-player/lib/ReactPlayer.js 中的错误模块构建失败:ReferenceError:“C:\work\website\node_modules\react-player\ 中指定的未知插件“transform-es3-member-expression-literals” package.json.env.production" 在 0,尝试相对于 "C:\work\website\node_modules\react-player" 进行解析

我已经从 babel 中排除了 node_modules:

  rules: [
      {
        test: /\.js$/, // Transform all .js files required somewhere with Babel
        exclude: /node_modules\/(?!(react-redux-toastr)\/).*/,
        use: {
          loader: 'babel-loader',
          options: options.babelQuery,
        },
      },

按要求,

webpack.base.babel.js:

/**
 * COMMON WEBPACK CONFIGURATION
 */

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = options => ({
  mode: options.mode,
  entry: options.entry,
  output: Object.assign(
    {
      // Compile into js/build.js
      path: path.resolve(process.cwd(), 'build'),
      publicPath: '/',
    },
    options.output
  ), // Merge with env dependent settings
  optimization: options.optimization,
  node: {
    fs: 'empty',
    net: 'empty',
  },
  module: {
    rules: [
      {
        test: /\.js$/, // Transform all .js files required somewhere with Babel
        exclude: /node_modules\/(?!(react-redux-toastr)\/).*/,
        use: {
          loader: 'babel-loader',
          options: options.babelQuery,
        },
      },
      {
        test: /\.(scss|css)$/,
        use: [
          {
            loader:
              options.mode === 'development'
                ? 'style-loader'
                : MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: process.env.NODE_ENV === 'development',
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: process.env.NODE_ENV === 'development',
            },
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: process.env.NODE_ENV === 'development',
            },
          },
        ],
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
        exclude: /images/,
        use: 'file-loader',
      },
      {
        test: /\.(jpg|png|gif)$/,
        use: [
          {
            loader: 'file-loader',
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
              },
              optipng: {
                optimizationLevel: 7,
              },
              gifsicle: {
                interlaced: false,
              },
              pngquant: {
                quality: '65-90',
                speed: 4,
              },
            },
          },
        ],
      },
      {
        test: /\.svg$/,
        include: /sprite/,
        use: 'svg-sprite-loader',
      },
      {
        test: /\.svg$/,
        use: 'url-loader',
        exclude: /sprite/,
      },
      {
        test: /\.html$/,
        use: 'html-loader',
      },
      {
        test: /\.(mp4|webm)$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
          },
        },
      },
    ],
  },
  plugins: options.plugins.concat([
    new webpack.ProvidePlugin({
      // make fetch available
      fetch: 'exports-loader?self.fetch!whatwg-fetch',
    }),

    // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
    // inside your code for any environment checks; UglifyJS will automatically
    // drop any unreachable code.
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV),
        API_V: JSON.stringify(process.env.API_V),
        CONTENT_PREVIEW: JSON.stringify(process.env.CONTENT_PREVIEW),
      },
    }),
  ]),
  resolve: {
    modules: ['app', 'node_modules'],
    extensions: ['.js', '.jsx', '.react.js'],
    mainFields: ['browser', 'main', 'jsnext:main'],
  },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
  performance: options.performance || {},
});

webpack.projd.babel.js:

// Important modules this config uses
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = require('./webpack.base.babel')({
  mode: 'production',
  // In production, we skip all hot-reloading stuff
  entry: [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,
    nodeEnv: 'production',
    sideEffects: true,
    concatenateModules: true,
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.(scss|css)$/,
          chunks: 'all',
          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,
    }),

    new WebpackPwaManifest({
      name: 'LEDA',
      short_name: 'LEDA',
      description: '',
      background_color: '#ffffff',
      theme_color: '#00bae4',
      icons: [
        {
          src: path.resolve('app/images/favicon.png'),
          sizes: [72, 96, 120, 128, 144, 152, 167, 180, 192],
        },
      ],
    }),

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

    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),

    new UglifyJsPlugin({
      parallel: true,
      uglifyOptions: {
        ecma: 6,
      },
      cache: path.join(__dirname, 'webpack-cache/uglify-cache'),
    }),
  ],

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

webpack.dev.babel.js:

    /**
 * DEVELOPMENT WEBPACK CONFIGURATION
 */

const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const logger = require('../../server/logger');
const cheerio = require('cheerio');
const pkg = require(path.resolve(process.cwd(), 'package.json'));
const dllPlugin = pkg.dllPlugin;

const plugins = [
  new webpack.ContextReplacementPlugin(
    /\.\/locale$/,
    'empty-module',
    false,
    /js$/
  ),
  new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
  new webpack.ContextReplacementPlugin(
    /\.\/locale$/,
    'empty-module',
    false,
    /js$/
  ),
  new HtmlWebpackPlugin({
    inject: true, // Inject all files that are generated by webpack, e.g. bundle.js
    templateContent: templateContent(), // eslint-disable-line no-use-before-define
  }),
  new CircularDependencyPlugin({
    exclude: /a\.js|node_modules|components\/Routes/, // exclude node_modules
    failOnError: false, // show a warning when there is a circular dependency
  }),
];

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

  // Add hot reloading in development
  entry: [
    'eventsource-polyfill', // Necessary for hot reloading with IE
    'webpack-hot-middleware/client?reload=true',
    path.join(process.cwd(), 'internals/dev-preamble.js'),
    path.join(process.cwd(), 'app/app.js'), // Start with js/app.js
  ],

  // Don't use hashes in dev mode for better performance
  output: {
    filename: '[name].js',
    chunkFilename: '[name].chunk.js',
  },

  optimization: {
    minimize: false,
  },

  // Add development plugins
  plugins: dependencyHandlers().concat(plugins), // eslint-disable-line no-use-before-define

  // Tell babel that we want to hot-reload
  babelQuery: {
    // require.resolve solves the issue of relative presets when dealing with
    // locally linked packages. This is an issue with babel and webpack.
    // See https://github.com/babel/babel-loader/issues/149 and
    // https://github.com/webpack/webpack/issues/1866
    presets: ['babel-preset-react-hmre'].map(require.resolve),
  },

  // Emit a source map for easier debugging
  devtool: 'inline-source-map',

  performance: {
    hints: false,
  },
});

/**
 * Select which plugins to use to optimize the bundle's handling of
 * third party dependencies.
 *
 * If there is a dllPlugin key on the project's package.json, the
 * Webpack DLL Plugin will be used.
 *
 */
function dependencyHandlers() {
  // Don't do anything during the DLL Build step
  if (process.env.BUILDING_DLL) {
    return [];
  }

  // Don't do anything if package.json does not have a dllPlugin property
  // Code splitting now included by default in Webpack 4
  if (!dllPlugin) {
    return [];
  }

  const dllPath = path.resolve(
    process.cwd(),
    dllPlugin.path || 'node_modules/react-boilerplate-dlls'
  );

  /**
   * If DLLs aren't explicitly defined, we assume all production dependencies listed in package.json
   * Reminder: You need to exclude any server side dependencies by listing them in dllConfig.exclude
   */
  if (!dllPlugin.dlls) {
    const manifestPath = path.resolve(dllPath, 'reactBoilerplateDeps.json');

    if (!fs.existsSync(manifestPath)) {
      logger.error(
        'The DLL manifest is missing. Please run `npm run build:dll`'
      );
      process.exit(0);
    }

    return [
      new webpack.DllReferencePlugin({
        context: process.cwd(),
        manifest: require(manifestPath), // eslint-disable-line global-require
      }),
    ];
  }

  // If DLLs are explicitly defined, we automatically create a DLLReferencePlugin for each of them.
  const dllManifests = Object.keys(dllPlugin.dlls).map(name =>
    path.join(dllPath, `/${name}.json`)
  );

  return dllManifests.map(manifestPath => {
    if (!fs.existsSync(path)) {
      if (!fs.existsSync(manifestPath)) {
        logger.error(
          `The following Webpack DLL manifest is missing: ${path.basename(
            manifestPath
          )}`
        );
        logger.error(`Expected to find it in ${dllPath}`);
        logger.error('Please run: npm run build:dll');

        process.exit(0);
      }
    }

    return new webpack.DllReferencePlugin({
      context: process.cwd(),
      manifest: require(manifestPath), // eslint-disable-line global-require
    });
  });
}

/**
 * We dynamically generate the HTML content in development so that the different
 * DLL Javascript files are loaded in script tags and available to our application.
 */
function templateContent() {
  const html = fs
    .readFileSync(path.resolve(process.cwd(), 'app/index.html'))
    .toString();

  if (!dllPlugin) {
    return html;
  }

  const doc = cheerio(html);
  const body = doc.find('body');
  const dllNames = !dllPlugin.dlls
    ? ['reactBoilerplateDeps']
    : Object.keys(dllPlugin.dlls);

  dllNames.forEach(dllName =>
    body.append(`<script data-dll='true' src='/${dllName}.dll.js'></script>`)
  );

  return doc.toString();
}

最后是 webpack.dll.babel.js:

/**
 * WEBPACK DLL GENERATOR
 *
 * This profile is used to cache webpack's module
 * contexts for external library and framework type
 * dependencies which will usually not change often enough
 * to warrant building them from scratch every time we use
 * the webpack process.
 */

const { join } = require('path');
const defaults = require('lodash/defaultsDeep');
const webpack = require('webpack');
const pkg = require(join(process.cwd(), 'package.json'));
const dllPlugin = require('../config').dllPlugin;

if (!pkg.dllPlugin) {
  process.exit(0);
}

const dllConfig = defaults(pkg.dllPlugin, dllPlugin.defaults);
const outputPath = join(process.cwd(), dllConfig.path);

module.exports = require('./webpack.base.babel')({
  mode: 'development',
  context: process.cwd(),
  entry: dllConfig.dlls ? dllConfig.dlls : dllPlugin.entry(pkg),
  optimization: {
    minimize: false,
  },
  devtool: 'eval',
  output: {
    filename: '[name].dll.js',
    path: outputPath,
    library: '[name]',
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]',
      path: join(outputPath, '[name].json'),
    }),
  ],
  performance: {
    hints: false,
  },
});

包.json:

{
  "name": "react-boilerplate",
  "version": "3.4.0",
  "description": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices",
  "repository": {
    "type": "git",
    "url": "git://github.com/react-boilerplate/react-boilerplate.git"
  },
  "engines": {
    "npm": ">=3",
    "node": ">=5"
  },
  "author": "Max Stoiber",
  "license": "MIT",
  "scripts": {
    "analyze:clean": "rimraf stats.json",
    "preanalyze": "npm run analyze:clean",
    "analyze": "node ./internals/scripts/analyze.js",
    "checkversion": "node ./internals/scripts/checkversion.js",
    "preinstall": "npm run checkversion",
    "postinstall": "npm run build:dll",
    "prebuild": "npm run build:clean",
    "build": "webpack --config internals/webpack/webpack.prod.babel.js --color --progress",
    "build:prod": "cross-env NODE_ENV=production API_V=production npm run build",
    "build:staging": "cross-env NODE_ENV=production API_V=staging npm run build",
    "build:clean": "npm run test:clean",
    "build:dll": "node ./internals/scripts/dependencies.js",
    "start": "cross-env NODE_ENV=development node server",
    "start:preview": "cross-env NODE_ENV=development CONTENT_PREVIEW=true node server",
    "start:tunnel": "cross-env NODE_ENV=development ENABLE_TUNNEL=true node server",
    "start:production": "npm run test && npm run build:prod && npm run start:prod",
    "start:staging": "npm run test && npm run build:staging && npm run start:prod",
    "start:prod": "cross-env NODE_ENV=production node server",
    "presetup": "npm i chalk shelljs",
    "setup": "node ./internals/scripts/setup.js",
    "postsetup": "npm run build:dll",
    "clean:all": "npm run analyze:clean && npm run test:clean && npm run build:clean",
    "lint": "npm run lint:js",
    "lint:eslint": "eslint",
    "lint:js": "npm run lint:eslint -- . ",
    "lint:fix": "npm run lint:eslint -- . --fix",
    "lint:staged": "lint-staged",
    "pretest:coverage": "npm run test:clean",
    "test:clean": "rimraf ./coverage",
    "test": "cross-env NODE_ENV=test jest",
    "test:update": "cross-env NODE_ENV=test jest --updateSnapshot",
    "test:coverage": "cross-env NODE_ENV=test jest --coverage",
    "test:watch": "cross-env NODE_ENV=test jest --watch",
    "coveralls": "cat ./coverage/lcov.info | coveralls",
    "flow": "flow; test $? -eq 0 -o $? -eq 2"
  },
  "lint-staged": {
    "*.js": "lint:eslint",
    "*.{js,scss}": [
      "prettier --write",
      "git add"
    ]
  },
  "pre-commit": [
    "lint:staged",
    "test"
  ],
  "dllPlugin": {
    "path": "node_modules/react-boilerplate-dlls",
    "exclude": [
      "chalk",
      "compression",
      "cross-env",
      "express",
      "ip",
      "minimist"
    ],
    "include": [
      "core-js",
      "lodash",
      "eventsource-polyfill"
    ]
  },
  "jest": {
    "collectCoverageFrom": [
      "app/**/*.{js,jsx}",
      "!app/**/*.test.{js,jsx}",
      "!app/containers/**/*.{js,jsx}",
      "!app/*/RbGenerated*/*.{js,jsx}",
      "!app/app.js",
      "!app/routes.js"
    ],
    "moduleDirectories": [
      "node_modules",
      "app"
    ],
    "moduleNameMapper": {
      ".*\\.(css|less|styl|scss|sass)$": "<rootDir>/internals/mocks/cssModule.js",
      ".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/mocks/image.js"
    },
    "setupTestFrameworkScriptFile": "<rootDir>/internals/testing/test-bundler.js",
    "testRegex": "tests/.*\\.test\\.js$",
    "setupFiles": [
      "<rootDir>/internals/testing/test-setup.js"
    ]
  },
  "dependencies": {
    "axios": "^0.15.3",
    "babel-polyfill": "6.20.0",
    "bluebird": "^3.5.0",
    "chalk": "1.1.3",
    "classnames": "^2.2.5",
    "compression": "1.6.2",
    "cross-env": "3.1.3",
    "express": "4.14.0",
    "fontfaceobserver": "2.0.7",
    "history": "4.6.3",
    "immutable": "3.8.2",
    "ip": "1.1.4",
    "leaflet": "^1.0.3",
    "lodash": "4.17.2",
    "marked": "^0.3.6",
    "mime-types": "^2.1.16",
    "minimist": "1.2.0",
    "moment": "^2.18.1",
    "moment-timezone": "^0.5.13",
    "numeral": "^2.0.6",
    "pace": "0.0.4",
    "pace-js": "^1.0.2",
    "prerender-node": "^2.7.2",
    "qs": "^6.4.0",
    "react": "15.4.1",
    "react-dom": "15.4.1",
    "react-foundation-components": "^0.12.0",
    "react-helmet": "5.0.0",
    "react-hot-loader": "^4.0.0",
    "react-loadable": "^5.3.1",
    "react-modal": "^1.7.7",
    "react-player": "^1.5.0",
    "react-progressbar.js": "^0.2.0",
    "react-redux": "4.4.6",
    "react-redux-toastr": "^7.0.0",
    "react-router": "4.2.0",
    "react-router-dom": "^4.2.2",
    "react-router-redux": "5.0.0-alpha.6",
    "react-router-scroll-memory": "^1.0.1",
    "redux": "3.6.0",
    "redux-immutable": "3.0.8",
    "redux-saga": "0.16.0",
    "redux-segment": "^1.6.2",
    "request-promise": "^4.2.1",
    "shortid": "^2.2.8",
    "sitemap": "^1.13.0",
    "store": "^2.0.4",
    "tls": "0.0.1",
    "tunnel-agent": "^0.6.0"
  },
  "devDependencies": {
    "axios-mock-adapter": "^1.8.1",
    "babel-cli": "6.18.0",
    "babel-core": "6.21.0",
    "babel-eslint": "7.1.1",
    "babel-loader": "^7.1.4",
    "babel-plugin-add-module-exports": "^0.2.1",
    "babel-plugin-dynamic-import-node": "1.0.0",
    "babel-plugin-react-transform": "2.0.2",
    "babel-plugin-root-import": "^5.1.0",
    "babel-plugin-transform-es2015-modules-commonjs": "6.18.0",
    "babel-plugin-transform-react-constant-elements": "6.9.1",
    "babel-plugin-transform-react-inline-elements": "6.8.0",
    "babel-plugin-transform-react-jsx-source": "^6.22.0",
    "babel-plugin-transform-react-remove-prop-types": "0.2.11",
    "babel-preset-env": "^1.6.1",
    "babel-preset-latest": "6.16.0",
    "babel-preset-react": "6.16.0",
    "babel-preset-react-hmre": "1.1.1",
    "babel-preset-stage-0": "6.16.0",
    "cheerio": "0.22.0",
    "circular-dependency-plugin": "^5.0.1",
    "coveralls": "2.11.15",
    "css-loader": "^0.28.11",
    "empty-module": "0.0.2",
    "enzyme": "2.6.0",
    "eslint": "^3.19.0",
    "eslint-config-airbnb": "^14.1.0",
    "eslint-config-airbnb-base": "^11.1.3",
    "eslint-config-prettier": "^2.6.0",
    "eslint-import-resolver-webpack": "0.8.3",
    "eslint-plugin-flowtype": "^2.30.4",
    "eslint-plugin-import": "2.2.0",
    "eslint-plugin-jsx-a11y": "^4.0.0",
    "eslint-plugin-prettier": "^2.3.1",
    "eslint-plugin-react": "7.5.1",
    "eslint-plugin-redux-saga": "0.1.5",
    "eventsource-polyfill": "0.9.6",
    "exports-loader": "^0.7.0",
    "file-loader": "^1.1.11",
    "flow-bin": "^0.57.3",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "husky": "^0.14.3",
    "image-webpack-loader": "^4.2.0",
    "imports-loader": "^0.8.0",
    "jest": "^22.4.3",
    "jest-cli": "^22.4.3",
    "lint-staged": "^3.2.1",
    "mini-css-extract-plugin": "^0.4.0",
    "ngrok": "2.2.4",
    "node-plop": "0.5.4",
    "node-sass": "^4.5.3",
    "null-loader": "0.1.1",
    "plop": "1.7.3",
    "postcss-loader": "^2.1.3",
    "pre-commit": "1.1.3",
    "prettier": "^1.7.4",
    "react-addons-test-utils": "15.4.1",
    "redux-logger": "^2.10.2",
    "rimraf": "2.5.4",
    "sass-loader": "^6.0.7",
    "shelljs": "0.7.5",
    "sinon": "2.0.0-pre",
    "style-loader": "^0.20.3",
    "svg-sprite-loader": "^3.7.3",
    "uglifyjs-webpack-plugin": "^1.2.4",
    "url-loader": "^1.0.1",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14",
    "webpack-dev-middleware": "^3.1.2",
    "webpack-hot-middleware": "^2.22.0",
    "webpack-pwa-manifest": "^3.6.2"
  }
}
4

3 回答 3

3

您需要安装被询问的插件:

npm install --save-dev babel-plugin-transform-es3-member-expression-literals
于 2018-05-17T17:35:35.510 回答
1
 new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: '"production"',
  },
}),

你可以试试。

于 2018-05-09T06:42:46.817 回答
0

原来问题与macos/windows反斜杠和正斜杠差异有关,将排除模式切换为:

排除:/(node_modules|bower_components!react-redux-toastr)/

解决它。

于 2018-05-20T10:43:32.710 回答