GithubHelp home page GithubHelp logo

bohdantkachenko / webpack-split-by-path Goto Github PK

View Code? Open in Web Editor NEW
110.0 5.0 21.0 161 KB

Split a Webpack entry bundle by path into any number of arbitrarily defined smaller bundles

License: MIT License

JavaScript 90.30% CSS 0.40% HTML 9.30%

webpack-split-by-path's Introduction

NPM

Dependency Status Average time to resolve an issue Percentage of issues still open

Split By Path Webpack Plugin

This plugin will split a Webpack entry bundle into any number of arbitrarily defined smaller bundles.

Based on Split by Name Webpack Plugin.

Unlike original component, it uses absolute path to identify bundle.

Why?

  • Browsers will open [between 6 and 10][browserscope] parallel connections to a single host. By splitting up one large file (your main bundle) into a number of smaller ones, you can leverage these connections to download the files [faster][stevesouders].
  • It's likely that you will have some third party scripts which you change infrequently. By putting these into their own bundle, then if they haven't changed between builds, your users may still be able to use the cached version from before.

How?

Configuration of the plugin is simple. You instantiate the plugin with an array of objects, each containing the keys name and path. Any modules which are in your entry chunk which match the bucket's path (first matching bucket is used), are then moved to a new chunk with the given name.

path should be an absolute path string value. It can be also an array of such values.

Creating a 'catch-all' bucket is not necessary: anything which doesn't match one of the defined buckets will be left in the original chunk.

Now, by separating the manifest info into a standalone chunk, vendor chunks(something like that) will stay the same with or without hashing unless you change their version.

API

new SplitByPathPlugin(chunks, options);

  • chunks - array of objects { name: string, path: string | string[] }
  • options - object, optional { ignore: string | string[], ignoreChunks: string | string[], manifest: string }
new SplitByPathPlugin([
  { name: 'c1', path: 'src/c1' },
  { name: 'vendor', path: path.join(__dirname, 'node_modules/')},
  ...chunkN
], {
  ignore: [
    'path/to/ingore/file/or/dir1',
    'path/to/ingore/file/or/dir2'
  ]
});

Example

var SplitByPathPlugin = require('webpack-split-by-path');
module.exports = {
  entry: {
    app: 'app.js'
  },
  output: {
    path: __dirname + '/public',
    filename: "[name]-[chunkhash].js",
    chunkFilename: "[name]-[chunkhash].js"
  },
  plugins: [
    new SplitByPathPlugin([
      {
        name: 'vendor',
        path: path.join(__dirname, 'node_modules')
      }
    ], {
      manifest: 'app-entry'
    })
  ]
};

So every module that is being requested from node_modules will be placed in public/vendor.js and everything else will be placed in public/app.js.

webpack-split-by-path's People

Contributors

aweber1 avatar baodelta avatar bohdantkachenko avatar e-cloud avatar greenkeeper[bot] avatar khurrumqureshi avatar ndelangen avatar sheerun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

webpack-split-by-path's Issues

webpack-dev-server 2.8.1 triggers a bug in webpack-split-by-path

Running into this issue.

6% basic chunk optimization/home/project/node_modules/webpack-split-by-path/index.js:167
if (ignore[i].test(resourcePath)) {
^

TypeError: ignore[i].test is not a function

Webpack configuration:

const SplitByPathPlugin = require('webpack-split-by-path');

new SplitByPathPlugin([ {name: 'vendor', path: path.join(__dirname, 'node_modules')}, ], {ignore: [/style-loader/, /css-loader/, /less-loader/, /\.scss$/, /\.css$/]} ),

This issue is we have a polyfilled includes method on array. This breaks webpack
bundle generation since polyfill method is iterated in for loop.

for (var i in ignore) { if (ignore[i].test(resourcePath)) { return match; } }

This is caused by webpack-dev-server > 2.7.1.
Suggestion would be update for loop to iterate on own properties. I can submit pull req after some discussion to ensure I'm not the only one with this issue.

Not working when adding methods to Array.prototype

Hi there,
Curiously, while my application was running great when launching webpack server from source files, I could not get it to build with webpack-split. I got this error:

D:\dev\stime\projects\wks\d-marketing\d-marketing-ui\node_modules\webpack-split-by-path\index.js:70
      if (ignore[i].test(userRequest)) {
                    ^
TypeError: ignore[i].test is not a function

While debugging, I noticed 1st that the 'ignore' array was empty. Then, I also noticed that ignore[i] was actually returning a method.
Reason was I overloaded the Array.prototype object with a custom method I use a lot in my code (more convenient this way, imo), but the loop being used (for ... in) loops over the object, not the array. So the inject method is called, has no 'test' method and it bugs (=> no build!!!)

Is it possible to change this loop into:

for (var i = 0; i < ignore.length; ++i) {
      if (ignore[i].test(userRequest)) {
        return match;
      }
    }

So that we can overload Array.prototype without error when building with webpack?

chunk order Not work well with html-webpack-plugin

now the generated output is good, but when using with html-webpack-plugin, in my case, the generated script tag order is not what expected.

i.e. one possible result for now.

...
<script type="text/javascript" src="manifest_ed6c67841e.js"></script>
<script type="text/javascript" src="main_4c9ecd6b3d.js"></script>
<script type="text/javascript" src="vendor_265cd3b016.js"></script>
...

the expected result

<script type="text/javascript" src="manifest_ed6c67841e.js"></script>
<script type="text/javascript" src="vendor_265cd3b016.js"></script>
<script type="text/javascript" src="main_4c9ecd6b3d.js"></script>

i think this result is caused by the chunk order or priority.
As the manifest chunk is the entry chunk, of course i will have highest priority.
But the others' order is sorted by webpack. So, We should level up the extracted chunks priority.

However, i can't find a solution according to the webpack document.
Therefore I need someone's help.

@sokra, @bebraw, could you guys give some expertise?

The chunkFilename doesn't actually do what's expected

I am using the v0.10 of this plugin with Webpack v1.13 and the plugin is using the filename pattern, instead of the chunkFilename pattern.
I am not sure if that is intended, or unexpected side effect of the way this plugin is configured...

"Cannot read property 'bind' of undefined"

I'm encountering an error when using this plugin with the Webpack@4 beta.

TypeError: Cannot read property 'bind' of undefined
    at /Users/alexlrobertson/Sites/project/node_modules/webpack-split-by-path/index.js:87:35
    at SyncBailHook.eval (eval at create (/Users/alexlrobertson/Sites/project/node_modules/tapable/lib/HookCodeFactory.js:17:12), <anonymous>:12:16)
    at SyncBailHook.lazyCompileHook [as _call] (/Users/alexlrobertson/Sites/project/node_modules/tapable/lib/Hook.js:35:21)
    at Compilation.seal (/Users/alexlrobertson/Sites/project/node_modules/webpack/lib/Compilation.js:785:30)
    at hooks.make.callAsync.err (/Users/alexlrobertson/Sites/project/node_modules/webpack/lib/Compiler.js:439:17)
    at _err0 (eval at create (/Users/alexlrobertson/Sites/project/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:11:1)
    at _addModuleChain (/Users/alexlrobertson/Sites/project/node_modules/webpack/lib/Compilation.js:672:11)
    at processModuleDependencies.err (/Users/alexlrobertson/Sites/project/node_modules/webpack/lib/Compilation.js:614:8)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)"

Upgrade to 0.0.3 breaks bundling CSS files with Webpack

I have pretty simple structure for my project,

static/
- css/
  - app.css
- projectname/
  - App.js

And App.js contains an import of ../css/app.css file,

import "../css/app.css";

My webpack config is pretty simple too,

  new SplitByPathPlugin([
    {
      "name": "vendors",
      "path": path.join(__dirname, "node_modules"),
    },
  ]),

And everything works fine with webpack#1.12.1 and webpack-split-by-path#0.0.2. But when I tried to update SplitByPathPlugin to 0.0.3 version everything became broken, and I start getting weird errors in console,

ERROR in ./static/css/app.css
Module build failed: TypeError: undefined is not a function
    at Object.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/extract-text-webpack-plugin/loader.js:100:11)
    at Compiler.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compiler.js:214:10)
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compiler.js:403:12
    at Compiler.next (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:67:11)
    at Compiler.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/extract-text-webpack-plugin/loader.js:78:5)
    at Compiler.next (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:69:14)
    at Compiler.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/CachePlugin.js:40:4)
    at Compiler.applyPluginsAsync (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:71:13)
    at Compiler.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compiler.js:400:9)
    at Compilation.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:576:13)
    at Compilation.applyPluginsAsync (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69)
    at Compilation.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:571:10)
    at Compilation.applyPluginsAsync (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69)
    at Compilation.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:566:9)
    at Compilation.applyPluginsAsync (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69)
    at Compilation.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:562:8)
    at Compilation.applyPluginsAsync (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69)
    at Compilation.seal (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:524:7)
    at Compiler.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compiler.js:397:15)
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/tapable/lib/Tapable.js:103:11
    at Compilation.<anonymous> (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:444:10)
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:416:12
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:331:10
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:52:16
    at done (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:248:21)
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:44:16
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/lib/Compilation.js:331:10
    at /Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:52:16
    at Object.async.forEachOf.async.eachOf (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:236:20)
    at Object.async.forEach.async.each (/Users/playpauseandstop/Projects/projectname/node_modules/webpack/node_modules/async/lib/async.js:215:22)
 @ ./static/projectname/App.js 25:0-25

And as result app.css file not built on.

So I'm wondering what changed in 0.0.3 which results breaking CSS bundling with webpack?

Release v3.0.0 ?

Looks like package.json has been updated to 3.0.0, but NPM is still out of date. Can we get a release cut?

NPM version 2.0.0, github version 2.0.0

Hi,
Your last merge from a PR solves deprecation warnings from webpack 3. Version in github is 2.0.1 but NPM version is 2.0.0. Maybe you need to "npm publish" it ?

Regards

Does not work well with ExtractText Plugin

I'm trying to use your awesome plugin together with ExtractText plugin, in begining I got problems with text.forEach is not a function, but thanks to the aid of @GreenGremlin I found that adding ignore regexps containing the css-loader path and /.css$/ (and the same for less in my case ) solves the error, however the created css does not contain all of the code from the vendor bucket (again relevant to my case)
this issues is related to this issue
webpack/extract-text-webpack-plugin/#92

the relevant parts of my config shortened for brevity, actually using 3 files to merge into webpack config so I have reference of the created plugin in the loaders section:

plugins:[new SplitByPathPlugin([{
        name: 'vendor',
        path: [path.join(basePath, 'node_modules'), path.join(basePath, 'frontEnd', 'lib'), path.join(basePath, 'frontEnd', 'core', 'libs')]
    }], {ignore: [/style-loader/, /css-loader/, /less-loader/, /\.less$/, /\.css$/]}),new ExtractTextPlugin('css/vendor.css', {
        allChunks: false
    }), new ExtractTextPlugin('css/[name].css', {
        allChunks: false
    })],
module:{loaders:[
{test: /\.css(\?.*)?$/, loader: plugins.extractCss.extract('style-loader', "css-loader?sourceMap", {allChunks: false, disable: false})},
{
        test: /\.less(\?.*)?$/,
        loader: plugins.extractLess.extract('style-loader', 'css-loader?sourceMap!less-loader?{"sourceMap":true,"modifyVars":' + JSON.stringify(colors) + '}', {
            allChunks: false,
            disable: false
        })
]]}


Do you have any idea how to overcome this?
thanks

Split by path and split by name at the same time

I'm running a configuration where the Split by path plugin splits my vendors:

new SplitByPathPlugin([
    {
        name: 'vendor',
        path: [
            path.join(__dirname, 'bower_components'),
            path.join(__dirname, 'node_modules')
        ]
    }
])

and the SplitByName plugin splits my views:

new SplitByNamePlugin({
    buckets: [
        {
            name: 'views',
            regex: /\.html/
        }
    ]
})

While this works, only the first one in the order does anything (if views get compiled first, vendors aren't and vice versa based on the order of plugins). Is there a way to make these two work together, or can you think of a way that would allow me to use only SplitByPath for both my views and my vendors?

Views are located under the app/src/any-component/_resources/views. There are numerous components.

Also let me thank you for this great plugin, it's a life saver as it finally got me somewhere. Any help is appreciated.

Syntax error in Windows

SyntaxError: Invalid regular expression: /^G:\Dev\node_modules\/: \ at end of pattern

Windows uses "" as a path delimiter so any path ending in a slash will raise a syntax error from the regular expression return new RegExp('^' + path);.

Does not work in windows

The problem is that windows paths start with a drive letter.
You are escaping the path in the function regExpQuote(str), but i think it escapes too much.
When I changed according to http://stackoverflow.com/a/6969486/1353412 to

function regExpQuote(str) {
  return (str + '').replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

it worked well.

Does not play nice with CompressionPlugin

If I use both SplitByPathPlugin to break out a vendor.js and CompressionPlugin to compress the resulting bundles, then only the vendor.js bundle is compressed. The primary (index.js) bundle is not compressed.

Chunk Order is incorrect

Reproduction: split-by-path-bug-master.zip

The output order appears to be manifest, app, vendor when it should be manifest, vendor, app.

This issue was most recently brought up in #18

Edit: I added the dist folder to the repository just in case left-pad goes off grid again.

0.1.0 Breaks in Webpack Dev Server

Haven't been able to nail down exactly what's wrong, but after first compile, if i change a source file, and refresh the app, there is an error in the manifest.
screen shot 2016-07-25 at 6 03 20 pm

v0.0.10 does not exhibit the problem, so I'm pinned to that for now.

In Safari, when splitting by node_modules, Can't find variable: webpackJsonp

I'm using code very much like that suggested in the readme to split node_modules into a vendors file and the rest into an app file.

In Safari I'm seeing the error ReferenceError: Can't find variable: webpackJsonp when the page loads.

Here's the config:

var SplitByPathPlugin, config, dev, path, webpack;

path = require('path');

SplitByPathPlugin = require('webpack-split-by-path');

webpack = require('webpack');

require('dotenv').config({
  silent: true
});

dev = (process.env.NODE_ENV || 'development') === 'development';

config = {
  entry: {
    app: path.resolve(__dirname, 'src', 'javascripts', 'main.jsx')
  },
  output: {
    path: path.resolve(__dirname, 'public', 'javascripts'),
    filename: '[name].js',
    chunkFilename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react']
        }
      }, {
        test: /\.css$/,
        loader: 'style!css'
      }, {
        test: /\.scss$/,
        loader: 'style!css!sass'
      }
    ]
  },
  plugins: [
    new SplitByPathPlugin([
      {
        name: 'vendors',
        path: path.join(__dirname, 'node_modules')
      }
    ])
  ]
};

if (dev) {
  config.devtool = 'source-map';
} else {
  config.plugins.push(new webpack.optimize.UglifyJsPlugin({
    minimize: true
  }));
}

module.exports = config;

When googling for this error I saw some results which talk about the Commons plugin, but not about this one. The only solutions appeared to be to remove the Commons plugin.

Is this a bug, or do I have something wrong with my configuration?

Error: Chunk.entry was removed. Use hasRuntime()

The latest webpack release (2.1.0-beta.17) raises the following error:

node_modules/webpack/lib/Chunk.js:34
        throw new Error("Chunk.entry was removed. Use hasRuntime()");
        ^

Error: Chunk.entry was removed. Use hasRuntime()
    at Chunk.Object.defineProperty.get (node_modules/webpack/lib/Chunk.js:34:9)
    at node_modules/webpack-split-by-path/index.js:91:23
    at Array.filter (native)
    at Compilation.<anonymous> (node_modules/webpack-split-by-path/index.js:89:10)
    at Compilation.applyPluginsBailResult (node_modules/webpack/node_modules/tapable/lib/Tapable.js:52:27)
    at Compilation.seal (node_modules/webpack/lib/Compilation.js:543:8)
    at Compiler.<anonymous> (node_modules/webpack/lib/Compiler.js:436:15)
    at node_modules/webpack/node_modules/tapable/lib/Tapable.js:152:11
    at Compilation.<anonymous> (node_modules/webpack/lib/Compilation.js:434:10)
    at node_modules/webpack/lib/Compilation.js:410:12
    at node_modules/webpack/lib/Compilation.js:325:10
    at node_modules/async/lib/async.js:52:16
    at done (node_modules/async/lib/async.js:246:17)
    at node_modules/async/lib/async.js:44:16
    at node_modules/webpack/lib/Compilation.js:325:10
    at node_modules/async/lib/async.js:52:16

Seems to be related to index.js:91

Also see this related issue on the webpack repo: webpack/webpack#2764

And this commit to the extract-text plugin for a similar problem may be of help: webpack-contrib/extract-text-webpack-plugin@ba0a71d

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.