Open sanwv opened 7 years ago
I would expect that you could do the same thing with the externals plugin:
var pages = glob.sync('*.page.js', {cwd: cwd + '/src/pages', matchBase: true});
var entry = {};
var htmls = [];
var externalsPlugins = [];
var externalsByPage = {
'help.html': [
{ module: 'react', entry: 'dist/react.min.js', global: 'React' },
{ module: 'react-dom', entry: 'dist/react-dom.min.js', global: 'ReactDOM' }
],
'admin.html': [
{ module: 'react', entry: 'dist/react.min.js', global: 'React' },
{ module: 'react-dom', entry: 'dist/react-dom.min.js', global: 'ReactDOM' },
{ module: 'moment', entry: 'moment.js', global: 'moment' }
]
};
pages.forEach((item) => {
let chunk = 'pages/' + item.slice(0, 0 - '.page.js'.length);
entry[chunk] = ['./src/pages/' + item];
var filename = path.resolve('./build') + '/' + item.slice(0, 0 - '.page.js'.length) + '.html';
htmls.push(new HtmlWebpackPlugin({
filename: filename,
template: path.resolve(cwd, 'src/htmls/index.html'),
chunks: [chunk],
hash: true
}))
externalsPlugins.push(new HtmlWebpackExternalsPlugin({
externals: externalsByPage[filename],
files: filename
}));
});
webpackConfig.plugins = webpackConfig.plugins.concat(htmls, externalsPlugins);
Yes, but when we have hundreds of pages,more than twenty packages ,the way will be troublesome and config file too length. Not perfect
in the question,i also got the way like your, the README is very detailed。 in fact ,we can also directly written in the html webpack plugin template.
Can you only define an external module list, according to the degree of dependence on a page automatically import the required external?
like webpack ‘externals’ config is a map for all entry, loaded on demand
I am not sure if this is possible. It is something I will look into. I think that HtmlWebpackPlugin has already generated the HTML output before Webpack has generated a full list of all packages that are imported.
I wrote a test plugin that seemed to get the result.
DepsPlugin.prototype.apply = function (compiler) {
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-before-html-processing', function (htmlPluginData, callback) {
console.log('haha,enter again and again!');
let externalDepMap = {};
compilation.entries.forEach(entry => {
let name = entry.name;
externalDepMap[name] = [];
entry.dependencies.forEach(dep => {//dep=SingleEntryDependency
dep.module.dependencies.forEach(_dep => {//_dep=[ConstDependency,CommonJsRequireDependency,RequireHeaderDependency,...]
if (_dep.module && _dep.module.external) {
externalDepMap[name].push(_dep.module.userRequest);
}
})
});
})
console.log(externalDepMap);//externalDepMap maybe need be cached!
console.log(Object.keys(htmlPluginData.assets.chunks)[0]);
callback(null, htmlPluginData);
});
}.bind(this));
}
Usually an application will have a lot of pages, so it is not possible to use
files
specify a page will append which external resource. if have a way to import externals automatically according import situcation in src files.for example, one file (admin.html) need react,moment, another only need react(help.html). i configed all externals in plugin options. in build file, admin.html have react,moment scripts and help.html only react script.
this is me how to config webpack entry and html-webpack-plugin: