Skip to content

Commit

Permalink
Mutiple cdn modules for mutiple pages app (#13)
Browse files Browse the repository at this point in the history
* add mutiple cdn modules for mutiple page app

* test case

* change test module

* feat(readme): update readme,#13

* fix(module.js): remove the debug code, and fix eslint error
  • Loading branch information
likun7981 authored and shirotech committed Jan 31, 2018
1 parent 4ab160a commit 037b0c0
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 58 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,49 @@ Please see the [example](example) folder for a basic working example.

You can pass an object options to WebpackCdnPlugin. Allowed values are as follows:

##### `modules`:`array`
##### `modules`:`array` or `object`(for mutiple pages)

The available options for each module, which is part of an array.
If you want inject cdn for mutiple pages, you can config like this:

```js
plugins:[
// ...otherConfig
new HtmlWebpackPlugin({
title: 'title',
cdnModule: 'vue',
favicon: 'path/to/favicon',
template: 'path/to/template',
filename: 'filename',
// other config
}),
new HtmlWebpackPlugin({
title: 'title',
cdnModule: 'react',
favicon: 'path/to/favicon',
template: 'path/to/template',
filename: 'filename',
// other config
}),
new WebpackCdnPlugin({
modules: {
'vue': [
{ name: 'vue', var: 'Vue', path: 'dist/vue.min.js' },
],
'react': [
{ name: 'react', var: 'React', path: `umd/react.${process.env.NODE_ENV}.min.js` },
{ name: 'react-dom', var: 'ReactDOM', path: `umd/react-dom.${process.env.NODE_ENV}.min.js` },
]
}
})
]
```

The extra `html-webpack-plugin` option `cdnModule` corresponds to the configuration __key__ that you config inside the `webpack-cdn-plugin` modules
- If you do not give `cdnModule` this value, the default is to take the first one
- If you set `cdnModule = false`, it will not inject cdn

More detail to see [#13](https://github.com/van-nguyen/webpack-cdn-plugin/pull/13)

`name`:`string`

Expand Down
72 changes: 44 additions & 28 deletions module.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ const empty = '';
const slash = '/';
const packageJson = 'package.json';
const paramsRegex = /:([a-z]+)/gi;
const DEFAULT_MODULE_KEY = 'defaultCdnModuleKey____';

class WebpackCdnPlugin {
constructor({
modules, prod,
prodUrl = '//unpkg.com/:name@:version/:path',
devUrl = ':name/:path', publicPath,
}) {
this.modules = modules;
this.modules = Array.isArray(modules) ? { [DEFAULT_MODULE_KEY]: modules } : modules;
this.prod = prod !== false;
this.prefix = publicPath;
this.url = this.prod ? prodUrl : devUrl;
Expand All @@ -31,19 +32,28 @@ class WebpackCdnPlugin {
this.prefix += slash;
}

const getArgs = [this.modules, this.url, this.prefix, this.prod, output.publicPath];
const getArgs = [this.url, this.prefix, this.prod, output.publicPath];

compiler.plugin('compilation', (compilation) => {
compilation.plugin('html-webpack-plugin-before-html-generation', (data, callback) => {
data.assets.js = WebpackCdnPlugin._getJs(...getArgs).concat(data.assets.js);
data.assets.css = WebpackCdnPlugin._getCss(...getArgs).concat(data.assets.css);
const moduleId = data.plugin.options.cdnModule;
if (moduleId !== false) {
const modules = this.modules[moduleId || Reflect.ownKeys(this.modules)[0]];
if (modules) {
data.assets.js = WebpackCdnPlugin._getJs(modules, ...getArgs).concat(data.assets.js);
data.assets.css = WebpackCdnPlugin._getCss(modules, ...getArgs).concat(data.assets.css);
}
}
callback(null, data);
});
});

const externals = compiler.options.externals || {};
this.modules.forEach((p) => {
externals[p.name] = p.var || p.name;

Reflect.ownKeys(this.modules).forEach((key) => {
const mods = this.modules[key];
mods.forEach((p) => {
externals[p.name] = p.var || p.name;
});
});

compiler.options.externals = externals;
Expand All @@ -57,35 +67,41 @@ class WebpackCdnPlugin {
prefix = prefix || empty;
prod = prod !== false;

return modules.filter(p => p.localStyle).map((p) => publicPath + p.localStyle).concat(modules.filter(p => p.style).map((p) => {
p.version = WebpackCdnPlugin.getVersion(p.name);
return modules
.filter(p => p.localStyle)
.map(p => publicPath + p.localStyle)
.concat(modules.filter(p => p.style).map((p) => {
p.version = WebpackCdnPlugin.getVersion(p.name);

return prefix + url.replace(paramsRegex, (m, p1) => {
if (prod && p.cdn && p1 === 'name') {
return p.cdn;
}
return prefix + url.replace(paramsRegex, (m, p1) => {
if (prod && p.cdn && p1 === 'name') {
return p.cdn;
}

return p[p1 === 'path' ? 'style' : p1];
});
}));
return p[p1 === 'path' ? 'style' : p1];
});
}));
}

static _getJs(modules, url, prefix, prod, publicPath) {
prefix = prefix || empty;
prod = prod !== false;

return modules.filter(p => p.localScript).map((p) => publicPath + p.localScript).concat(modules.filter(p => !p.cssOnly).map((p) => {
p.version = WebpackCdnPlugin.getVersion(p.name);
p.path = p.path || require.resolve(p.name).match(/[\\/]node_modules[\\/].+?[\\/](.*)/)[1].replace(/\\/g, '/');

return prefix + url.replace(paramsRegex, (m, p1) => {
if (prod && p.cdn && p1 === 'name') {
return p.cdn;
}

return p[p1];
});
}));
return modules
.filter(p => p.localScript)
.map(p => publicPath + p.localScript)
.concat(modules.filter(p => !p.cssOnly).map((p) => {
p.version = WebpackCdnPlugin.getVersion(p.name);
p.path = p.path || require.resolve(p.name).match(/[\\/]node_modules[\\/].+?[\\/](.*)/)[1].replace(/\\/g, '/');

return prefix + url.replace(paramsRegex, (m, p1) => {
if (prod && p.cdn && p1 === 'name') {
return p.cdn;
}

return p[p1];
});
}));
}
}

Expand Down
Loading

0 comments on commit 037b0c0

Please sign in to comment.