Webpack 动态加载代码拆分包
Webpack loading code split bundles on the fly
所以我想使用 webpack 将我的应用程序代码分成 3 个包。我能够让我的框架包加载和工作,但我无法让其他两个包即时加载。这是我的 webpack 配置:
var fs = require('fs'),
path = require('path'),
webpack = require('webpack'),
apps = fs.readdirSync('./app');
appModuleRegex = new RegExp("^(" + apps.join('|') + ")/(.*)$");
module.exports = {
context: 'app',
entry: {
framework: 'framework/app',
operations: 'operations/app',
platform: 'platform/app'
},
output: {
path: '/web/dist/',
filename: '[name].entry.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /\.test.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
}
]
},
resolveLoader: {
root: path.join(process.cwd(), "node_modules")
},
resolve: {
modulesDirectories: ['node_modules', 'bower_components'],
},
plugins: [
new webpack.NormalModuleReplacementPlugin(appModuleRegex, function(result) {
result.request = result.request.replace(appModuleRegex, "/web/app//src/");
}),
new webpack.NormalModuleReplacementPlugin(/fetch/, function(result) {
console.log("TRANSFORMING fetch");
result.request = 'isomorphic-fetch';
}),
// new webpack.optimize.CommonsChunkPlugin("commons.js")
],
devServer: {
contentBase: '/web/dist/'
}
}
基本上,如果 URL 匹配,我会使用 React router 尝试加载其他应用程序包:
class NotFound extends React.Component {
render () {
return null;
}
componentDidMount () {
var path = this.context.router.getCurrentPath(),
appName = path.split('/')[1];
if (appName === 'operations') {
require('./operations.entry.js');
}
else if (appName === 'platform') {
require('./platform.entry.js');
}
}
}
但是 webpack 似乎不喜欢这种模式:
weave_1 | ERROR in ./app/framework/src/app.js
weave_1 | Module not found: Error: Cannot resolve 'file' or 'directory' ./operations.entry.js in /web/app/framework/src
weave_1 | @ ./app/framework/src/app.js 131:16-45
weave_1 |
weave_1 | ERROR in ./app/framework/src/app.js
weave_1 | Module not found: Error: Cannot resolve 'file' or 'directory' ./platform.entry.js in /web/app/framework/src
weave_1 | @ ./app/framework/src/app.js 136:16-43
但是我可以在我的 dist 目录中看到这个结构:
css/
index.html
media/
platform.entry.js
framework.entry.js
js/
operations.entry.js
所以我认为这会很好。 index.html
正在加载 framework.entry.js
代码。有什么想法吗?
所以我最后做这件事的 hacky 方法是即时注入其他包:
class NotFound extends React.Component {
render () {
return null;
}
componentDidMount () {
var path = this.context.router.getCurrentPath(),
splitPath = path.split('/'),
appName = splitPath[1];
(function(d, script) {
script = d.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = appName + '.bundle.js';
d.getElementsByTagName('head')[0].appendChild(script);
}(document));
}
}
所以我想使用 webpack 将我的应用程序代码分成 3 个包。我能够让我的框架包加载和工作,但我无法让其他两个包即时加载。这是我的 webpack 配置:
var fs = require('fs'),
path = require('path'),
webpack = require('webpack'),
apps = fs.readdirSync('./app');
appModuleRegex = new RegExp("^(" + apps.join('|') + ")/(.*)$");
module.exports = {
context: 'app',
entry: {
framework: 'framework/app',
operations: 'operations/app',
platform: 'platform/app'
},
output: {
path: '/web/dist/',
filename: '[name].entry.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /\.test.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
}
]
},
resolveLoader: {
root: path.join(process.cwd(), "node_modules")
},
resolve: {
modulesDirectories: ['node_modules', 'bower_components'],
},
plugins: [
new webpack.NormalModuleReplacementPlugin(appModuleRegex, function(result) {
result.request = result.request.replace(appModuleRegex, "/web/app//src/");
}),
new webpack.NormalModuleReplacementPlugin(/fetch/, function(result) {
console.log("TRANSFORMING fetch");
result.request = 'isomorphic-fetch';
}),
// new webpack.optimize.CommonsChunkPlugin("commons.js")
],
devServer: {
contentBase: '/web/dist/'
}
}
基本上,如果 URL 匹配,我会使用 React router 尝试加载其他应用程序包:
class NotFound extends React.Component {
render () {
return null;
}
componentDidMount () {
var path = this.context.router.getCurrentPath(),
appName = path.split('/')[1];
if (appName === 'operations') {
require('./operations.entry.js');
}
else if (appName === 'platform') {
require('./platform.entry.js');
}
}
}
但是 webpack 似乎不喜欢这种模式:
weave_1 | ERROR in ./app/framework/src/app.js
weave_1 | Module not found: Error: Cannot resolve 'file' or 'directory' ./operations.entry.js in /web/app/framework/src
weave_1 | @ ./app/framework/src/app.js 131:16-45
weave_1 |
weave_1 | ERROR in ./app/framework/src/app.js
weave_1 | Module not found: Error: Cannot resolve 'file' or 'directory' ./platform.entry.js in /web/app/framework/src
weave_1 | @ ./app/framework/src/app.js 136:16-43
但是我可以在我的 dist 目录中看到这个结构:
css/
index.html
media/
platform.entry.js
framework.entry.js
js/
operations.entry.js
所以我认为这会很好。 index.html
正在加载 framework.entry.js
代码。有什么想法吗?
所以我最后做这件事的 hacky 方法是即时注入其他包:
class NotFound extends React.Component {
render () {
return null;
}
componentDidMount () {
var path = this.context.router.getCurrentPath(),
splitPath = path.split('/'),
appName = splitPath[1];
(function(d, script) {
script = d.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = appName + '.bundle.js';
d.getElementsByTagName('head')[0].appendChild(script);
}(document));
}
}