-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] New vendor bundle block #188
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# @webpack-blocks/vendor-bundle - Changelog | ||
|
||
## 1.0.0 | ||
|
||
Initial release. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Webpack blocks - vendor bundle | ||
|
||
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) | ||
[![NPM Version](https://img.shields.io/npm/v/@webpack-blocks/vendor-bundle.svg)](https://www.npmjs.com/package/@webpack-blocks/vendor-bundle) | ||
|
||
This block for [webpack-blocks](https://github.com/andywer/webpack-blocks) extracts a vendor bundle that includes the most used dependencies of your app. | ||
|
||
## Usage | ||
|
||
```js | ||
const { createConfig } = require('@webpack-blocks/webpack') | ||
const vendorBundle = require('@webpack-blocks/vendorBundle') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change |
||
|
||
module.exports = createConfig([ | ||
vendorBundle(/* options */) | ||
]) | ||
``` | ||
|
||
## Options | ||
|
||
#### name *(default: main)* | ||
|
||
Name of the main bundle of your app. | ||
|
||
#### filename *(default: vendor.[chunkhash].js)* | ||
|
||
Output bundle file name. | ||
|
||
#### minChunks *(default: 1)* | ||
|
||
Minimal number of chunks to include dependency into the bundle. | ||
|
||
#### exclude *(optional)*, string, array of strings, RegExp or array of RegExps | ||
|
||
Modules to exclude from the bundle. | ||
|
||
## Generated webpack config | ||
|
||
By default generates this configuration: | ||
|
||
```js | ||
{ | ||
plugins: [ | ||
new webpack.optimize.CommonsChunkPlugin({ | ||
name: 'main', | ||
filename: 'vendor.[chunkhash].js', | ||
children: true, | ||
minChunks ({ userRequest }, count) { | ||
return userRequest && userRequest.includes('node_modules') && | ||
userRequest.endsWith('.js') && | ||
count >= options.minChunks | ||
} | ||
}) | ||
] | ||
} | ||
``` | ||
|
||
## Webpack blocks | ||
|
||
Check out the | ||
|
||
👉 [Main Documentation](https://github.com/andywer/webpack-blocks) | ||
|
||
Released under the terms of the MIT license. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import test from 'ava' | ||
const webpack = require('webpack') | ||
import { createConfig } from '@webpack-blocks/core' | ||
import vendorBundle from '../index' | ||
|
||
const moduleInNode = { | ||
userRequest: '/Users/gendalf/moria/node_modules/decko/dist/decko.js' | ||
} | ||
const moduleInNode2 = { | ||
userRequest: '/Users/gendalf/moria/node_modules/lodash/noop.js' | ||
} | ||
const moduleNotInNode = { | ||
userRequest: '/Users/gendalf/moria/src/components/Button.js' | ||
} | ||
|
||
test('Vendor bundle default options work', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle() | ||
]) | ||
|
||
t.true(config.plugins[0] instanceof webpack.optimize.CommonsChunkPlugin) | ||
t.false(config.plugins[0].minChunks(moduleNotInNode, 1)) | ||
t.false(config.plugins[0].minChunks(moduleInNode, 0)) | ||
t.true(config.plugins[0].minChunks(moduleInNode, 1)) | ||
}) | ||
|
||
test('Vendor bundle minChunks option', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle({ | ||
minChunks: 42 | ||
}) | ||
]) | ||
|
||
t.false(config.plugins[0].minChunks(moduleNotInNode, 50)) | ||
t.false(config.plugins[0].minChunks(moduleInNode, 20)) | ||
t.true(config.plugins[0].minChunks(moduleInNode, 50)) | ||
}) | ||
|
||
test('Vendor bundle exclude option, string', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle({ | ||
exclude: 'lodash' | ||
}) | ||
]) | ||
|
||
t.true(config.plugins[0].minChunks(moduleInNode, 1)) | ||
t.false(config.plugins[0].minChunks(moduleInNode2, 1)) | ||
}) | ||
|
||
test('Vendor bundle exclude option, RegExp', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle({ | ||
exclude: /lodash/ | ||
}) | ||
]) | ||
|
||
t.true(config.plugins[0].minChunks(moduleInNode, 1)) | ||
t.false(config.plugins[0].minChunks(moduleInNode2, 1)) | ||
}) | ||
|
||
test('Vendor bundle exclude option, string[]', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle({ | ||
exclude: ['lodash'] | ||
}) | ||
]) | ||
|
||
t.true(config.plugins[0].minChunks(moduleInNode, 1)) | ||
t.false(config.plugins[0].minChunks(moduleInNode2, 1)) | ||
}) | ||
|
||
test('Vendor bundle exclude option, RegExp[]', t => { | ||
const config = createConfig({}, [ | ||
vendorBundle({ | ||
exclude: [/lodash/] | ||
}) | ||
]) | ||
|
||
t.true(config.plugins[0].minChunks(moduleInNode, 1)) | ||
t.false(config.plugins[0].minChunks(moduleInNode2, 1)) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* Vendor bundle webpack block. | ||
*/ | ||
|
||
const webpack = require('webpack') | ||
|
||
module.exports = vendorBundle | ||
|
||
/** | ||
* @param {object} filepath | ||
* @param {string|string[]|RegExp|RegExp[]} exclude | ||
*/ | ||
function hasBeenExcluded (filepath, exclude) { | ||
if (!exclude) { | ||
return false | ||
} else if (Array.isArray(exclude)) { | ||
return exclude.some(item => hasBeenExcluded(filepath, item)) | ||
} else if (exclude instanceof RegExp) { | ||
return exclude.test(filepath) | ||
} | ||
|
||
return filepath.includes(exclude) | ||
} | ||
|
||
/** | ||
* @param {object} [options] | ||
* @param {string} [options.name=main] Name of the main bundle of your app. | ||
* @param {string} [options.filename=vendor.\[chunkhash\].js] Output bundle file name. | ||
* @param {string|string[]|RegExp|RegExp[]} [exclude] Modules to exclude. | ||
* @param {number} [options.minChunks=1] Minimal number of chunks to include dependency into the bundle. | ||
* @return {Function} | ||
*/ | ||
function vendorBundle (options = {}) { | ||
options = Object.assign({ | ||
name: 'main', | ||
filename: 'vendor.[chunkhash].js', | ||
minChunks: 1 | ||
}, options) | ||
|
||
return (context, util) => { | ||
const plugin = new webpack.optimize.CommonsChunkPlugin({ | ||
name: options.main, | ||
filename: options.filename, | ||
children: true, | ||
minChunks ({ userRequest }, count) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return userRequest && userRequest.includes('node_modules') && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
userRequest.endsWith('.js') && | ||
count >= options.minChunks && | ||
!hasBeenExcluded(userRequest, options.exclude) | ||
} | ||
}) | ||
return util.addPlugin(plugin) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@webpack-blocks/webpack
re-exportscreateConfig
from@webpack-blocks/core
.