一个NODE_ENV 引发的血案
1 表象 控制台报错
截图没有完整的截下来,其实右边行号并没有具体的行号, 显示为payment-809e8ff.js 1
很明显 这是 js语法错误 但是当点击开里面显示的是html内容 第一行的 红色错误
首先第一眼看到这样的问题 直观感受是这问题 基本无法定位
但是实际上仔细看下可以发现 这个html并不是我们引用这个js页面的html页面, 而是跳转到了默认的404,
当我们再复制实际的这个js链接 到新的tab栏访问 才发现这个资源不存在,由此得出问题原因 资源不存在
下面为具体收银台项目记录一下
引发这个问题的原因为 为修改了 NODE_ENV
我们先看一下webpack.config.js
if (isProduction()) {
config.output.publicPath = '';
config.output.path = path.resolve(__dirname, 'build', 'js');
config.output.filename = '[name]-[hash:7].js';
config.output.chunkFilename = '[name]-[chunkhash:7].js';
config.plugins = [
new CleanPlugin('build/'),
new AssetsPlugin({
path: path.resolve('build/'),
filename: 'manifest.json',
prettyPrint: true
}),
new webpack.optimize.UglifyJsPlugin({
mangle: true,
compress: {
warnings: false,
drop_console: true,
drop_debugger: true
}
})
];
} else if (process.env.NODE_ENV === 'pre_test') {
config.output.publicPath = '';
config.output.path = path.resolve(__dirname, 'build', 'js');
config.output.filename = '[name]-[hash:7].js';
config.output.chunkFilename = '[name]-[chunkhash:7].js';
config.plugins = [
new CleanPlugin('build/'),
new AssetsPlugin({
path: path.resolve('build/'),
filename: 'manifest.json',
prettyPrint: true
}),
new webpack.optimize.UglifyJsPlugin({
mangle: true,
compress: {
warnings: false
}
})
];
} else if (process.env.NODE_ENV === 'pre') {
config.output.publicPath = '';
config.output.path = path.resolve(__dirname, 'build', 'js');
config.output.filename = '[name]-[hash:7].js';
config.output.chunkFilename = '[name]-[chunkhash:7].js';
config.plugins = [
new CleanPlugin('build/'),
new AssetsPlugin({
path: path.resolve('build/'),
filename: 'manifest.json',
prettyPrint: true
}),
new webpack.optimize.UglifyJsPlugin({
mangle: true,
compress: {
warnings: false,
drop_console: true,
drop_debugger: true
}
})
];
} else {
config.output.publicPath = '/assets/';
config.plugins = [
new webpack.HotModuleReplacementPlugin()
];
config.entry.webpackDevServer= 'webpack/hot/only-dev-server';
config.devServer = {
clientLogLevel: 'warning',
historyApiFallback: true,
hot: true,
compress: true,
host: 'localhost',
port: 9191,
open: true,
publicPath: '',
quiet: true
}
}
上面可以看出不同的环境变量我们加载不同的方式,比如生产环境我们是加载本地打包后的js文件
而最后一个else 则是起的本地webpackdevserver
我们再来看一下引用js文件的地方
var webpack = function(extension, bundle){
if(process.env.NODE_ENV == 'production' || process.env.NODE_ENV == 'pre'){
var manifest = JSON.parse(fs.readFileSync(__dirname + '/build/manifest.json'));
var filename = manifest[bundle][extension];
console.log(extension)
if(extension == 'css'){
return `/build/${filename}`;
}else{
return `/build/${extension}/${filename}`;
}
} else if(process.env.NODE_ENV == 'pre_test'){
var manifest = JSON.parse(fs.readFileSync(__dirname + '/build/manifest.json'));
var filename = manifest[bundle][extension];
return `/build/${extension}/${filename}`;
} else{
return `http://localhost:9191/assets/${bundle}.${extension}`;
}
}
同样这里的功能和上面差不多根据不同的环境来决定是走本地文件还是走热启动的地址
我们只需要在html里这么引用就可以了
<script type="text/javascript" src="<%= webpack('js', 'payment') %>"></script>
NODE_ENV 还对一个地方有影响的是 pm2 启动方式
pm2的启动json 文件 process.json
{
"apps": [{
"name": "joybuy",
"script": "/export/server/starfish/server.js",
"exec_mode": "cluster",
"instances": "max",
"log_date_format": "YYYY-MM-DD HH:mm Z",
"merge_logs": true,
"env": {
"NODE_ENV": "development"
},
"env_production": {
"NODE_ENV": "production"
},
"env_pre": {
"NODE_ENV": "pre"
}
}],
"deploy": {
}
}
启动pm2 的命令
pm2 start /export/server/starfish/process.json --env pre