Leveraging webpack2 for code splitting with the CommonsChunkPlugin

I encountered an issue while using code splitting and the CommonsChunkPlugin. My previous experience with require.js involved files being automatically cached. Additionally, I have configured my webpack with libraryTarget: 'amd'.

When looking at these two simple files, here is the resulting output:

// fileA.js
import $ from 'jquery'

// fileB.js
import $ from 'jquery'

   Asset    Size  Chunks                    Chunk Names
fileB.js  271 kB       0  [emitted]  [big]  fileB
fileA.js  271 kB       1  [emitted]  [big]  fileA

Both files, fileA and fileB, contain jquery. I am able to include these files in my html like this:

require(['./dist/fileA.js', './dist/fileB.js'], function () {
})

The documentation suggests using the CommonsChunkPlugin to extract jquery into its own file. So, my configuration now looks like this:

new webpack.optimize.CommonsChunkPlugin({
  name: 'common'
}),

This results in the following output:

    Asset       Size  Chunks                    Chunk Names
 fileB.js  635 bytes       0  [emitted]         fileB
 fileA.js  617 bytes       1  [emitted]         fileA
common.js     274 kB       2  [emitted]  [big]  common

However, now I am unable to use the above require block because the common.js also includes the webpack runtime. This leads to an error saying

Uncaught ReferenceError: webpackJsonp is not defined
.

To resolve this, I require the following setup:

  1. fileA.js (contains "fileA" code, requiring jquery)
  2. fileB.js (contains "fileB" code, requiring jquery)
  3. jquery.js (contains all jquery functionality)
  4. common.js (only contains webpack runtime)

I attempted something similar for fileA and fileB, but it resulted in the same output:

define(['jquery'], function ($) {

})

A vendor library should only be loaded if a script (like fileA) is loaded and has it as a dependency (as required in requirejs).

Is there a way to achieve this? I've checked the webpack2 docs multiple times but couldn't find anything helpful...

Edit: With guidance from various GitHub issues, I was able to correct the asset generation with the following configuration:

module.exports = {
  entry: {
    jquery: ['jquery'],
    vue: ['vue'],
    fileA: ['./src/fileA.js'],
    fileB: ['./src/fileB.js'],
    fileC: ['./src/fileC.js']
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist',
    filename: '[name].js',
    libraryTarget: 'amd'
  }
}

module.exports.plugins = (module.exports.plugins || []).concat([
  new webpack.optimize.CommonsChunkPlugin({
    name: ['vue', 'jquery']
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'common',
    chunks: ['vue', 'jquery'],
    minChunks: Infinity
  }),
  new webpack.optimize.OccurrenceOrderPlugin()
])

I updated the source files to include:

// fileA.js
import $ from 'jquery'
import Vue from 'vue'
// fileB.js
import $ from 'jquery'
// fileC.js
import Vue from 'vue'

Here is the updated output:

   vue.js     193 kB       0  [emitted]         vue
 fileC.js  447 bytes       1  [emitted]         fileC
 fileB.js  579 bytes       2  [emitted]         fileB
 fileA.js  666 bytes       3  [emitted]         fileA
jquery.js     269 kB       4  [emitted]  [big]  jquery
common.js    5.78 kB       5  [emitted]         common

Despite this, attempting to use it in an .html file leads to the following error:

<body>
  <script src="./dist/common.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.js"></script>
  <script>
    require(['./dist/fileA.js', './dist/fileB.js', './dist/fileC.js'], function (a, b, c) {
    })
  </script>
</body>

This error occurs both for fileA and fileC...

common.js:55 Uncaught TypeError: Cannot read property 'call' of undefined
    at __webpack_require__ (common.js:55)
    at Object.7 (fileA.js:16)
    at __webpack_require__ (common.js:55)
    at Object.6 (fileA.js:6)
    at __webpack_require__ (common.js:55)
    at webpackJsonpCallback (common.js:26)
    at fileA.js:1
    at Object.execCb (require.js:1696)
    at Module.check (require.js:883)
    at Module.enable (require.js:1176)

Edit:

I have created a repository on GitHub showcasing the issue I encountered. Following Rafael De Leon's suggestion, I now utilize System.import('<module>') to asynchronously import other files. The error seems to occur when output.js (the compiled main.ts file) requires fileA.ts using this syntax. I have also raised a concern in a GitHub issue as I suspect it may be a bug.

Answer №1

It is important to only load a (Vendor) library if a script, such as fileA, has it as a dependency (as seen with requirejs).

If you are seeking this outcome, CommonsChunkPlugin may not be the solution you need. This plugin is designed to combine files used by different entries or other CommonChunkPlugins into one file.

To achieve what you want, consider using import() or require.ensure for loading "vendor" files on demand.

Alternatively, you can refer to How to bundle vendor scripts separately and require them as needed with Webpack? for a solution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to iteratively process JSON array using JavaScript?

I am currently attempting to iterate through the JSON array provided below: { "id": "1", "msg": "hi", "tid": "2013-05-05 23:35", "fromWho": "<a href="/cdn-cgi/l/email-pro ...

I am experiencing issues with datejs not functioning properly on Chrome browser

I encountered an issue while trying to use datejs in Chrome as it doesn't seem to work properly. Is there a workaround for this problem if I still want to utilize this library? If not, can anyone recommend an excellent alternative date library that ...

Apache conf file configured with CSP not functioning properly when serving PHP files

While configuring the Apache CSP lockdown for a site, I encountered an unusual behavior when opening the same file as a PHP script compared to opening it as an HTML file. The HTML file looks like this: <html> <head> <meta http-equiv= ...

Even with employing Cors alongside Axios, I continue to encounter the following issue: The requested resource does not have the 'Access-Control-Allow-Origin' header

When working with a MEAN stack app, I had no issues with CORS. However, upon transitioning to the MERN stack, I encountered an error related to CORS despite having it implemented in the backend: Access to XMLHttpRequest at 'http://localhost:5000/api/ ...

Retrieving an array from the $.get() method within multiple nested loops

I'm currently working on a jQuery plugin that takes an array of JSON files and needs to compile them into one large array. While each part of the code works individually, I'm facing issues when trying to integrate them together and return the ne ...

Simple steps to change JSON Object to JavaScript array

Referring to this question and this other one, I am seeking advice on how to handle a JSON object structure different from the examples provided: This is my JSON Object: var myData = { "04c85ccab52880": { "name": "name1", "firstname": ...

Refresh Twitter Bootstrap Tooltip after deactivating/removing

I have a quick question. I am currently dealing with data that is constantly changing and displayed from a selected item in a table. To monitor for overflow, I have implemented the following code: if (event.target.offsetWidth < event.target.scrollW ...

Analyzing and swapping objects within two arrays

Looking for a better way to append an array of objects customData to another array testData? If there are duplicate objects with the same name, replace them in the resulting array while maintaining their order. Here's my current approach in ES6 - any ...

JavaScript stylesheet library

What is the top choice for an open-source JavaScript CSS framework to use? ...

Generate a fresh array using the data from the existing array object

I have nested objects within arrays that I need to manipulate. { "page": [ { "num": "1", "comp": [ { "foo": "bar", "bar": "foo", ...

Tips for achieving seamless scrolling with the combination of javascript and css

Looking for a solution to achieve smooth scrolling on an HTML page without using the #id_name to scroll to a specific div. Instead, I want to scroll to a particular point, such as having a button that scrolls down the webpage smoothly by 250px when press ...

exciting, showcasing a dependency map using svg within an html5 environment

I am working on creating a polygon background for my menu, which needs to be responsive in design. Here is an example of what I am trying to achieve: example image. Should I use JavaScript to listen for size changes and adjust the points for the polygon e ...

Creating a Vue Directive in the form of an ES6 class: A step-by-step

Is it possible to make a Vue directive as an ES6 Class? I have been attempting to do so, but it doesn't seem to be working correctly. Here is my code snippet: import { DirectiveOptions } from 'vue'; interface WfmCarriageDirectiveModel { ...

What is the process for changing the state of an array in graphql?

Currently, I am facing a challenge with adding an array to a GraphQl schema. Here is what it looks like: type Play { winRatio: [Float] } The intention behind the winRatio attribute is to store the history of all win ratios. For instance, after playing 3 ...

Button click event is not being triggered by Ajax rendering

I am facing an issue with my Django template that showcases scheduled classes for our training department. Each item in the list has a roster button which, when clicked, should display the class roster in a div. This functionality works perfectly. However, ...

Is it possible to incorporate an existing svg from the page into another svg element?

Currently, I am facing a challenge where I am programmatically creating logos as svgs with d3. Now, I have an svg map and I want to incorporate these logos into it. I am wondering if there is a way, whether through d3 or another method, to transfer these ...

What steps should I take to display a Modal upon a successful Oauth2 redirect?

I am currently working on an older web application that utilizes the portal/portlet architecture. Within the application, I have a feature that loads in a modal when accessed. The modal includes navigation functionality that allows customers to navigate t ...

Despite containing elements, Array.length incorrectly reports as 0 in React, JavaScript, and TypeScript

I have been working on storing persistent data for my Electron app using electron-json-storage. Initially, I tried using neDB but encountered an error, so I switched to another method. However, it seems that the issue is not with neDB but rather with my ow ...

When using Axios to GET from a local PHP file, it only retrieves the code instead of running

I've run into an issue accessing the API as it has CORS disabled, requiring me to make requests on the server side. Currently, I'm using React and Axios to send a GET request to a local php file that should trigger cURL execution. However, instea ...

Is there a way to verify the results of a Python script within a PHP webpage?

For my school project, I am creating a PHP website where I want to implement a Python code Quiz. I envision a scenario where users can input Python code in an on-page editor/IDE and the output is checked automatically using PHP If-function to determine cor ...