This section covers all methods available in code compiled with webpack. When using webpack to bundle your application, you can pick from a variety of module syntax styles including ES6, CommonJS, and AMD.
While webpack supports multiple module syntaxes, we recommend following a single syntax for consistency and to avoid odd behaviors/bugs. Actually webpack would enforce the recommendation for .mjs
files, .cjs
files or .js
files when their nearest parent package.json
file contains a "type"
field with a value of either "module"
or "commonjs"
. Please pay attention to these enforcements before you read on:
.mjs
or .js
with "type": "module"
in package.json
require
, module.exports
or exports
import './src/App.mjs'
instead of import './src/App'
(you can disable this enforcement with Rule.resolve.fullySpecified
).cjs
or .js
with "type": "commonjs"
in package.json
import
nor export
is available.wasm
with "type": "module"
in package.json
Version 2 of webpack supports ES6 module syntax natively, meaning you can use import
and export
without a tool like babel to handle this for you. Keep in mind that you will still probably need babel for other ES6+ features. The following methods are supported by webpack:
Statically import
the export
s of another module.
import MyModule from './my-module.js';
import { NamedExport } from './other-module.js';
You can also import
Data URI:
import 'data:text/javascript;charset=utf-8;base64,Y29uc29sZS5sb2coJ2lubGluZSAxJyk7';
import {
number,
fn,
} from 'data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgY29uc3QgZm4gPSAoKSA9PiAiSGVsbG8gd29ybGQiOw==';
Export anything as a default
or named export.
// Named exports
export var Count = 5;
export function Multiply(a, b) {
return a * b;
}
// Default export
export default {
// Some data...
};
function(string path):Promise
Dynamically load modules. Calls to import()
are treated as split points, meaning the requested module and its children are split out into a separate chunk.
if (module.hot) {
import('lodash').then((_) => {
// Do something with lodash (a.k.a '_')...
});
}
It is not possible to use a fully dynamic import statement, such as import(foo)
. Because foo
could potentially be any path to any file in your system or project.
The import()
must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an import()
call is included. For example, import(`./locale/${language}.json`)
will cause every .json
file in the ./locale
directory to be bundled into the new chunk. At run time, when the variable language
has been computed, any file like english.json
or german.json
will be available for consumption.
// imagine we had a method to get language from cookies or other storage
const language = detectVisitorLanguage();
import(`./locale/${language}.json`).then((module) => {
// do something with the translations
});
Inline comments to make features work. By adding comments to the import, we can do things such as name our chunk or select different modes. For a full list of these magic comments see the code below followed by an explanation of what these comments do.
// Single target
import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackExports: ["default", "named"] */
'module'
);
// Multiple possible targets
import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`./locale/${language}`
);
import(/* webpackIgnore: true */ 'ignored-module.js');
webpackIgnore
: Disables dynamic import parsing when set to true
.
webpackChunkName
: A name for the new chunk. Since webpack 2.6.0, the placeholders [index]
and [request]
are supported within the given string to an incremented number or the actual resolved filename respectively. Adding this comment will cause our separate chunk to be named [my-chunk-name].js instead of [id].js.
webpackMode
: Since webpack 2.6.0, different modes for resolving dynamic imports can be specified. The following options are supported:
'lazy'
(default): Generates a lazy-loadable chunk for each import()
ed module.'lazy-once'
: Generates a single lazy-loadable chunk that can satisfy all calls to import()
. The chunk will be fetched on the first call to import()
, and subsequent calls to import()
will use the same network response. Note that this only makes sense in the case of a partially dynamic statement, e.g. import(`./locales/${language}.json`)
, where multiple module paths that can potentially be requested.'eager'
: Generates no extra chunk. All modules are included in the current chunk and no additional network requests are made. A Promise
is still returned but is already resolved. In contrast to a static import, the module isn't executed until the call to import()
is made.'weak'
: Tries to load the module if the module function has already been loaded in some other way (e.g. another chunk imported it or a script containing the module was loaded). A Promise
is still returned, but only successfully resolves if the chunks are already on the client. If the module is not available, the Promise
is rejected. A network request will never be performed. This is useful for universal rendering when required chunks are always manually served in initial requests (embedded within the page), but not in cases where app navigation will trigger an import not initially served.webpackPrefetch
: Tells the browser that the resource is probably needed for some navigation in the future. Check out the guide for more information on how webpackPrefetch works.
webpackPreload
: Tells the browser that the resource might be needed during the current navigation. Check out the guide for more information on how webpackPreload works.
webpackInclude
: A regular expression that will be matched against during import resolution. Only modules that match will be bundled.
webpackExclude
: A regular expression that will be matched against during import resolution. Any module that matches will not be bundled.
webpackExports
: tells webpack to only bundle the specified exports of a dynamically import()
ed module. It can decrease the output size of a chunk. Available since webpack 5.0.0-beta.18.
The goal of CommonJS is to specify an ecosystem for JavaScript outside the browser. The following CommonJS methods are supported by webpack:
require(dependency: String);
Synchronously retrieve the exports from another module. The compiler will ensure that the dependency is available in the output bundle.
var $ = require('jquery');
var myModule = require('my-module');
It's possible to enable magic comments for require
as well, see module.parser.javascript.commonjsMagicComments
for more.
require.resolve(dependency: String);
Synchronously retrieve a module's ID. The compiler will ensure that the dependency is available in the output bundle. It is recommended to treat it as an opaque value which can only be used with require.cache[id]
or __webpack_require__(id)
(best to avoid such usage).
See module.id
for more information.
Multiple requires of the same module result in only one module execution and only one export. Therefore a cache in the runtime exists. Removing values from this cache causes new module execution and a new export.
var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;
// in file.js
require.cache[module.id] === module;
require('./file.js') === module.exports;
delete require.cache[module.id];
require.cache[module.id] === undefined;
require('./file.js') !== module.exports; // in theory; in praxis this causes a stack overflow
require.cache[module.id] !== module;
require.ensure(
dependencies: String[],
callback: function(require),
errorCallback: function(error),
chunkName: String
)
Split out the given dependencies
to a separate bundle that will be loaded asynchronously. When using CommonJS module syntax, this is the only way to dynamically load dependencies. Meaning, this code can be run within execution, only loading the dependencies
if certain conditions are met.
var a = require('normal-dep');
if (module.hot) {
require.ensure(['b'], function (require) {
var c = require('c');
// Do something special...
});
}
The following parameters are supported in the order specified above:
dependencies
: An array of strings declaring all modules required for the code in the callback
to execute.callback
: A function that webpack will execute once the dependencies are loaded. An implementation of the require
function is sent as a parameter to this function. The function body can use this to further require()
modules it needs for execution.errorCallback
: A function that is executed when webpack fails to load the dependencies.chunkName
: A name given to the chunk created by this particular require.ensure()
. By passing the same chunkName
to various require.ensure()
calls, we can combine their code into a single chunk, resulting in only one bundle that the browser must load.Asynchronous Module Definition (AMD) is a JavaScript specification that defines an interface for writing and loading modules. The following AMD methods are supported by webpack:
define([name: String], [dependencies: String[]], factoryMethod: function(...))
If dependencies
are provided, factoryMethod
will be called with the exports of each dependency (in the same order). If dependencies
are not provided, factoryMethod
is called with require
, exports
and module
(for compatibility!). If this function returns a value, this value is exported by the module. The compiler ensures that each dependency is available.
define(['jquery', 'my-module'], function ($, myModule) {
// Do something with $ and myModule...
// Export a function
return function doSomething() {
// ...
};
});
define(value: !Function)
This will export the provided value
. The value
here can be anything except a function.
define({
answer: 42,
});
require(dependencies: String[], [callback: function(...)])
Similar to require.ensure
, this will split the given dependencies
into a separate bundle that will be loaded asynchronously. The callback
will be called with the exports of each dependency in the dependencies
array.
require(['b'], function (b) {
var c = require('c');
});
The internal LabeledModulesPlugin
enables you to use the following methods for exporting and requiring within your modules:
Export the given value
. The label can occur before a function declaration or a variable declaration. The function name or variable name is the identifier under which the value is exported.
export: var answer = 42;
export: function method(value) {
// Do something...
};
Make all exports from the dependency available in the current scope. The require
label can occur before a string. The dependency must export values with the export
label. CommonJS or AMD modules cannot be consumed.
some-dependency.js
export: var answer = 42;
export: function method(value) {
// Do something...
};
require: 'some-dependency';
console.log(answer);
method(...);
Aside from the module syntaxes described above, webpack also allows a few custom, webpack-specific methods:
require.context(
(directory: String),
(includeSubdirs: Boolean) /* optional, default true */,
(filter: RegExp) /* optional, default /^\.\/.*$/, any file */,
(mode: String) /* optional, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once', default 'sync' */
);
Specify a whole group of dependencies using a path to the directory
, an option to includeSubdirs
, a filter
for more fine grained control of the modules included, and a mode
to define the way how loading will work. Underlying modules can then be easily resolved later on:
var context = require.context('components', true, /\.html$/);
var componentA = context.resolve('componentA');
If mode
is set to 'lazy'
, the underlying modules will be loaded asynchronously:
var context = require.context('locales', true, /\.json$/, 'lazy');
context('localeA').then((locale) => {
// do something with locale
});
The full list of available modes and their behavior is described in import()
documentation.
require.include((dependency: String));
Include a dependency
without executing it. This can be used for optimizing the position of a module in the output chunks.
require.include('a');
require.ensure(['a', 'b'], function (require) {
/* ... */
});
require.ensure(['a', 'c'], function (require) {
/* ... */
});
This will result in the following output:
file.js
and a
b
c
Without require.include('a')
it would be duplicated in both anonymous chunks.
Similar to require.resolve
, but this won't pull the module
into the bundle. It's what is considered a "weak" dependency.
if (__webpack_modules__[require.resolveWeak('module')]) {
// Do something when module is available...
}
if (require.cache[require.resolveWeak('module')]) {
// Do something when module was loaded before...
}
// You can perform dynamic resolves ("context")
// similarly to other require/import methods.
const page = 'Foo';
__webpack_modules__[require.resolveWeak(`./page/${page}`)];