问题
i am having troubles setting up webpack build configuration. i have two webpack config files, one for development and one for production.
everything works fine in dev environment, but when building for production, i get this error:
ReferenceError: _ref2 is not defined
at e.value (App.js:20)
at c (react-dom.production.min.js:147)
at beginWork (react-dom.production.min.js:150)
at i (react-dom.production.min.js:182)
at c (react-dom.production.min.js:183)
at l (react-dom.production.min.js:184)
at v (react-dom.production.min.js:188)
at h (react-dom.production.min.js:187)
at Object.updateContainer (react-dom.production.min.js:248)
at react-dom.production.min.js:254
so this is my webpack config files:
webpack.config.dev.js
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
// import 'babel-polyfill';
export default {
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: 'cheap-module-eval-source-map', // more info:https://webpack.js.org/guides/development/#using-source-maps and https://webpack.js.org/configuration/devtool/
entry: [
// must be first entry to properly set public path
'babel-polyfill',
'./src/webpack-public-path',
'react-hot-loader/patch',
'webpack-hot-middleware/client?reload=true',
path.resolve(__dirname, 'src/index.js') // Defining path seems necessary for this to work consistently on Windows machines.
],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'), // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'), // Tells React to build in either dev or prod modes. https://facebook.github.io/react/downloads.html (See bottom)
__DEV__: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new HtmlWebpackPlugin({ // Create HTML file that includes references to bundled CSS and JS.
template: 'src/index.ejs',
minify: {
removeComments: true,
collapseWhitespace: true
},
inject: true
})
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.eot(\?v=\d+.\d+.\d+)?$/,
use: ['file-loader']
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
]
},
{
test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml'
}
}
]
},
{
test: /\.(jpe?g|png|gif|ico)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
]
},
{
test: /(\.css|\.scss|\.sass)$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
}, {
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')
],
sourceMap: true
}
}, {
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, 'src', 'scss')],
sourceMap: true
}
}
]
}
]
}
};
webpack.config.prod.js
// For info about this file refer to webpack and webpack-hot-middleware documentation
// For info on how we're generating bundles with hashed filenames for cache busting: https://medium.com/@okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95#.w99i89nsz
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import WebpackMd5Hash from 'webpack-md5-hash';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
const GLOBALS = {
'process.env.NODE_ENV': JSON.stringify('production'),
__DEV__: false
};
export default {
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: 'source-map', // more info:https://webpack.js.org/guides/production/#source-mapping and https://webpack.js.org/configuration/devtool/
entry: ['babel-polyfill', './src/webpack-public-path', path.resolve(__dirname, 'src/index.js')],
target: 'web',
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '',
filename: '[name].[chunkhash].js'
},
plugins: [
// Hash the files using MD5 so that their names change when the content changes.
new WebpackMd5Hash(),
// Tells React to build in prod mode. https://facebook.github.io/react/downloads.html
new webpack.DefinePlugin(GLOBALS),
// Generate an external css file with a hash in the filename
new ExtractTextPlugin('[name].[contenthash].css'),
// Generate HTML file that contains references to generated bundles. See here for how this works: https://github.com/ampedandwired/html-webpack-plugin#basic-usage
new HtmlWebpackPlugin({
template: 'src/index.ejs',
favicon: 'src/favicon.ico',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
},
inject: true
}),
// Minify JS
new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.eot(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
name: 'fonts/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
name: 'img/[name].[contenthash].[ext]'
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[contenthash].[ext]'
}
}
]
},
{
test: /(\.css|\.scss|\.sass)$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
minimize: true,
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')
],
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, 'src', 'scss')],
sourceMap: true
}
}
]
})
}
]
}
};
.babelrc
{
"presets": [
"react",
"stage-1",
"flow"
],
"env": {
"development": {
"presets": [
"env",
"react-hmre"
],
"plugins": [
"transform-regenerator",
[
"transform-class-properties",
{
"spec": true
}
]
]
},
"production": {
"presets": [
[
"env",
{
"es2015": {
"modules": false
},
"targets": {
"ie": 9,
"uglify": true
}
}
]
],
"plugins": [
"transform-regenerator",
"transform-react-constant-elements",
"transform-react-remove-prop-types",
[
"transform-class-properties",
{
"spec": true
}
]
]
},
"test": {
"presets": [
"env"
],
"plugins": [
"transform-regenerator",
[
"transform-class-properties",
{
"spec": true
}
]
]
}
}
}
i have no idea which configuration may be causing this erros.
回答1:
I think this is not a webpack issue, it's App.js file.
In my case, there was a 'let' declaration issue. It was working in a dev environment but wasn't on a production build. Basically, in the build process, we need to take special care of const/let/function declarations order and scope, so that after the build, declaration reference will get actual declarations.
My case was:
const products = products.map(group => {
let resultButton = '';
if (!group.product[0].soldout) {
let price = 0;
price += group.product[0].amount.amount;
if (group.product[0].fees) {
for (let i = 0; i < group.product[0].fees.length; i += 1) {
price += group.product[0].fees[i].amount;
}
}
// here was my wrong declaration
// I corrected by declaring outside of if (!group.product[0].soldout)
// below let resultButton = '';
// & it works for me after build
let benefits = <li>No benefits defined</li>;
if (
group.product[0].properties&&
group.product[0].properties.length > 0
) {
_.map(group.product[0].properties.property, property => {
if (property.code === 51) {
const benefitsArray = property.content.split('\n');
benefits = benefitsArray.map(item => {
const st = item.replace(/ +/g, '');
return <li key={st}>{item}</li>;
});
}
});
}
resultButton = (
<div>
<h4>
<ul>{benefits}</ul>
</div>
);
} else {
resultButton = (
<div>
<SoldOut>
</div>
);
}
return resultButton;
});
Hope you'll get the answer.
来源:https://stackoverflow.com/questions/46942130/referenceerror-ref2-is-not-defined-react-dom-production-min-js