我有一个使用webpack 2构建的相当大的React应用程序。该应用程序作为现有站点内的SPA嵌入到Drupal站点中。 Drupal站点有一个复杂的gulp构建设置,我不能用webpack复制它,所以我决定保留它。
我已经使用DllPlugin / DllReferencePlugin组合将我的React应用程序拆分成多个部分,这个组合在webpack 2中开箱即用。这很好用,在使用webpack构建时我得到了一个很好的供应商包。
问题是当我尝试在gulp中运行我的webpack配置时,出现错误。我可能做错了,因为我还没有找到关于这种方法的大量文档,但是,它并没有为我工作。
在创建它之前,它似乎试图包含我的vendor-bundle中的清单文件。
每当我运行我定义的gulp任务之一时,如gulp react-vendor
我收到错误,说它无法解析vendor-manifest.json文件。
如果我另一方面在我的终端上运行webpack --config=webpack.dll.js
,webpack编译得很好而且没有错误。
我已经包含了我认为的相关文件。对此有任何帮助表示赞赏。
webpack.config.js
// Use node.js built-in path module to avoid path issues across platforms.
const path = require('path');
const webpack = require('webpack');
// Set environment variable.
const production = process.env.NODE_ENV === "production";
const appSource = path.join(__dirname, 'react/src/');
const buildPath = path.join(__dirname, 'react/build/');
const ReactConfig = {
entry: [
'./react/src/index.jsx'
],
output: {
path: buildPath,
publicPath: buildPath,
filename: 'app.js'
},
module: {
rules: [
{
exclude: /(node_modules)/,
use: {
loader: "babel-loader?cacheDirectory=true",
options: {
presets: ["react", "es2015", "stage-0"]
},
},
},
],
},
resolve: {
modules: [
path.join(__dirname, 'node_modules'),
'./react/src/'
],
extensions: ['.js', '.jsx', '.es6'],
},
context: __dirname,
devServer: {
historyApiFallback: true,
contentBase: appSource
},
// TODO: Split plugins based on prod and dev builds.
plugins: [
new webpack.DllReferencePlugin({
context: path.join(__dirname, "react", "src"),
manifest: require(path.join(__dirname, "react", "vendors", "vendor-manifest.json"))
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
filename: 'webpack-loader.js'
}),
]
};
// Add environment specific configuration.
if (production) {
ReactConfig.plugins.push(
new webpack.optimize.UglifyJsPlugin()
);
}
module.exports = [ReactConfig];
webpack.dll.js
const path = require("path");
const webpack = require("webpack");
const production = process.env.NODE_ENV === "production";
const DllConfig = {
entry: {
vendor: [path.join(__dirname, "react", "vendors", "vendors.js")]
},
output: {
path: path.join(__dirname, "react", "vendors"),
filename: "dll.[name].js",
library: "[name]"
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, "react", "vendors", "[name]-manifest.json"),
name: "[name]",
context: path.resolve(__dirname, "react", "src")
}),
// Resolve warning message related to the 'fetch' node_module.
new webpack.IgnorePlugin(/\/iconv-loader$/),
],
resolve: {
modules: [
path.join(__dirname, 'node_modules'),
],
extensions: ['.js', '.jsx', '.es6'],
},
// Added to resolve a dependency issue in this build #https://github.com/hapijs/joi/issues/665
node: {
net: 'empty',
tls: 'empty',
dns: 'empty'
}
};
if (production) {
DllConfig.plugins.push(
new webpack.optimize.UglifyJsPlugin()
);
}
module.exports = [DllConfig];
vendors.js (确定要添加到Dll的内容)
require("react");
require("react-bootstrap");
require("react-dom");
require("react-redux");
require("react-router-dom");
require("redux");
require("redux-form");
require("redux-promise");
require("redux-thunk");
require("classnames");
require("whatwg-fetch");
require("fetch");
require("prop-types");
require("url");
require("validator");
gulpfile.js
'use strict';
const gulp = require('gulp');
const webpack = require ('webpack');
const reactConfig = require('./webpack.config.js');
const vendorConfig = require('./webpack.dll.js');
// React webpack source build.
gulp.task('react-src', function (callback) {
webpack(reactConfig, function (err, stats) {
callback();
})
});
// React webpack vendor build.
gulp.task('react-vendor', function (callback) {
webpack(vendorConfig, function (err, stats) {
callback();
})
});
// Full webpack react build.
gulp.task('react-full', ['react-vendor', 'react-src']);
注意:
如果我首先使用带有webpack --config=webpack.dll.js
的终端构建我的vendor-bundle并创建vendor-manifest.json文件,那么我随后可以成功运行我的gulp任务而没有任何问题。
这不是很有用,因为这仍然不允许我使用webpack和gulp,因为我打算在新版本运行之前清理构建。
答案 0 :(得分:1)
我最终使用了问题末尾提到的解决方案。我首先构建我的DLL文件,然后我可以成功运行我的gulp webpack任务。
可以更容易地调试问题的一个变化是使用Gulp实用程序模块(gulp-util)来显示在使用gulp构建webpack期间可能出现的任何webpack错误。
我的最终gulp设置最终看起来像这样:
<强> gulpfile.js 强>
'use strict';
const gulp = require('gulp');
const gutil = require('gulp-util');
const webpack = require('webpack');
const reactConfig = require('./webpack.config.js');
const vendorConfig = require('./webpack.dll.js');
// React webpack source build.
gulp.task('react', function (callback) {
webpack(reactConfig, function (err, stats) {
if (err) {
throw new gutil.PluginError('webpack', err);
}
else {
gutil.log('[webpack]', stats.toString());
}
callback();
});
});
// React webpack vendor build.
gulp.task('react-vendor', function (callback) {
webpack(vendorConfig, function (err, stats) {
if (err) {
throw new gutil.PluginError('webpack', err);
}
else {
gutil.log('[webpack]', stats.toString());
}
callback();
});
});
// React: Rebuilds both source and vendor in the right order.
gulp.task('react-full', ['react-vendor'], function () {
gulp.start('react');
});
我希望这可以帮助处于类似情况的人。
答案 1 :(得分:1)
每当我运行一个已定义的gulp任务之一(例如gulp react-vendor)时,我都会收到一条错误消息,说它无法解析vendor-manifest.json文件。
您的gulpfile.js包含以下内容:
const reactConfig = require('./webpack.config.js');
const vendorConfig = require('./webpack.dll.js');
webpack.config.js包含以下内容:
new webpack.DllReferencePlugin({
context: path.join(__dirname, "react", "src"),
manifest: require(path.join(__dirname, "react", "vendors", "vendor-manifest.json"))
}),
require()
调用当前全部立即执行。每当您运行Gulp时,它将评估两个Webpack配置文件。按照当前配置,Node在启动时在webpack.config.js
中运行代码,并从那里看到创建DllReferencePlugin所使用的require()
,因此它还将尝试读取manifest.json
时间并把它变成一个对象……这是在构建之前的。
您可以通过以下两种方法之一解决此问题:
manifest
选项支持一个对象(这是您当前提供的对象),或者支持包含清单文件路径的字符串。换句话说,如果您从require()
通话中删除path.join(...)
,它应该可以工作。const reactConfig = require('./webpack.config.js');
从文件顶部直接移到gulp任务函数中就足够了,前提是要在构建清单之后才调用此函数。