Parcel: Does this tool support multiple entries and feature like `webpack.optimize.CommonsChunkPlugin`

Created on 8 Dec 2017  路  18Comments  路  Source: parcel-bundler/parcel

Choose one: 馃檵 feature request?

馃帥 Configuration (.babelrc, package.json, cli command)

// index.html
<script src="vendor.js"></script>
<script src="index.js"></script>
// index.js
import React from "react";

// other code
// vendor.js
import "react";
import "react-dom";

馃 Expected Behavior

https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin

馃槸 Current Behavior

馃拋 Possible Solution

馃敠 Context

My webpack config uses this feature, if this tool support this feature, I can try this tool rather than webpack.

馃實 Your Environment

Most helpful comment

We can accomplish chunks vendor splitting doing this:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Testing parcel</title>
    <link rel="stylesheet" href="../node_modules/bulma/css/bulma.css">
</head>
<body>
    <div id="root"></div>
    <script src="./js/main.js"></script>
</body>
</html>

main.js

import "./vendor";

import React from "react";
import ReactDOM from "react-dom";

import HomeComponent from "./home/home.component";

ReactDOM.render(<HomeComponent />, document.getElementById("root"));

vendor.js

// Create additional bundles for these libraries.
import("react");
import("react-dom");

home.component.jsx

import React from "react";

export default class HomeComponent extends React.Component {
  render() {
      return (
        <div>Hello world :)</div>
      );
  }
}

The result...

image

image

All 18 comments

This sounds pretty cool.

I鈥檓 trying to understand what commonschunkplugin does, but I don鈥檛 really understand the point. Do you mind explaining it a bit?

From my understanding the commonschunkplugin allows you to split out frequently used libraries into its own bundle so that they all get loaded at once and so you can have smaller application bundles.

commonschunkplugin works with code splitting, there is also a link about its point: https://webpack.js.org/guides/code-splitting/#prevent-duplication

If a module is already imported in vendor.js, it doesn't appear to get added in index.js bundle. Atleast from the bundle size, that what it appears to be when I tested.

Can anyone confirm?

@sudhakar That's right.
Usually, index.js changes frequently, vendor.js doesn't change, so bundled vendor.js's hash doesn't change too(eg, 500KB), so a browser will not load bundled vendor.js again when I just change index.js, it just reload bundled index.js(eg, 200KB).
Without commonschunkplugin, a browser will always reload whole js file(eg,700KB) even I just make a small change.

@plantain-00 I have used commonschunkplugin. Atleast from the bundle size it generated, looks like parcel already does it by default. AFAIK, no config or plugin is required to make it work like commonschunkplugin

So I would say give it a try :)

Here's a excerpt from the docs which confirms that

If an asset is required in more than one bundle, it is hoisted up to the nearest common ancestor in the bundle tree so it is not included more than once.

It seems it supports commonschunkplugin for development mode, production mode failed because of #8

Any intention to support similar functionality as CommonsChunkPlugin?
Very helpful for reducing download size in deployment of updates.

https://survivejs.com/webpack/building/bundle-splitting/

This already happens automatically. If you use a dynamic import to do code splitting, the common dependencies are automatically hoisted into the common bundle. See https://parceljs.org/code_splitting.html.

I read through that.

I can test this, but want to be clear on the intended/supported use case.

In the simplest case - If I want all my node_modules bundled into a common .js file, I could make a dummy .JS file that imports them e.g. React, use dynamic import on the dummy, and that will result in split bundles where my packages are hoisted into a common bundle?

In theory the common bundle JS should never change if I'm only changing my app src and don't import any more common modules, or don't update any packages.

I think I prefer the more explicit multiple entry point support with Webpack as the intent it is clear.

This ties in with my query in another issue for your website repo I commented on yesterday re cache busting and deployment strategies that Parcel could perhaps make easier with zero config

https://github.com/parcel-bundler/website/issues/59#issuecomment-361830177

We can accomplish chunks vendor splitting doing this:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Testing parcel</title>
    <link rel="stylesheet" href="../node_modules/bulma/css/bulma.css">
</head>
<body>
    <div id="root"></div>
    <script src="./js/main.js"></script>
</body>
</html>

main.js

import "./vendor";

import React from "react";
import ReactDOM from "react-dom";

import HomeComponent from "./home/home.component";

ReactDOM.render(<HomeComponent />, document.getElementById("root"));

vendor.js

// Create additional bundles for these libraries.
import("react");
import("react-dom");

home.component.jsx

import React from "react";

export default class HomeComponent extends React.Component {
  render() {
      return (
        <div>Hello world :)</div>
      );
  }
}

The result...

image

image

Really nice post, @sant123!

Just to add my penny, if anyone wants to try this solution, please make sure you use the rounded brackets syntax in the import statements you'd like to split out.

So e.g.:

import('react')

not

import 'react'

Is it possible to name these chunks?

Do you really need it? The name is according with the package you're importing.

We can accomplish chunks vendor splitting doing this:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Testing parcel</title>
    <link rel="stylesheet" href="../node_modules/bulma/css/bulma.css">
</head>
<body>
    <div id="root"></div>
    <script src="./js/main.js"></script>
</body>
</html>

main.js

import "./vendor";

import React from "react";
import ReactDOM from "react-dom";

import HomeComponent from "./home/home.component";

ReactDOM.render(<HomeComponent />, document.getElementById("root"));

vendor.js

// Create additional bundles for these libraries.
import("react");
import("react-dom");

home.component.jsx

import React from "react";

export default class HomeComponent extends React.Component {
  render() {
      return (
        <div>Hello world :)</div>
      );
  }
}

The result...

image

image

This solution will create tons of my vendor packaged files

@chris-kobrzak @sant123 i'm having some problems using the solution you are advocating above. I am successfully splitting React & ReactDOM from my main bundle but they are not being added to the index.html.
As a result this method essentially "lazy loads" react & react-dom meaning that their download is not initiated until the main bundle has finished downloading as you can see in these screenshots:

(before)
Screenshot 2019-04-24 15 03 28
(after)
Screenshot 2019-04-24 15 03 39

Do you have any idea where I might be going wrong here?

Update: I realise my vendor chunks are also not being given consistent names which is also different to your result. Probably part of the same problem?

Was this page helpful?
0 / 5 - 0 ratings