Currently, a "function-like" import()
module loading syntax proposal is on the way into ECMAScript.
The ES2015 Loader spec defines import()
as method to load ES2015 modules dynamically on runtime.
webpack treats import()
as a split-point and puts the requested module in a separate chunk. import()
takes the module name as argument and returns a Promise
: import(name) -> Promise
index.js
function determineDate() { import('moment').then(function(moment) { console.log(moment().format()); }).catch(function(err) { console.log('Failed to load moment', err); }); } determineDate();
Keep in mind thatimport()
path cannot be fully dynamic (e.g.,import(Math.random())
). Rather either completely static (e.g.,import('./locale/de.json')
) or partially static (e.g.,import('./locale/' + language + '.json')
).
import()
relies onPromise
internally.
If you use import()
with older browsers, remember to shim Promise
using a polyfill such as es6-promise or promise-polyfill.
In an entry point of your application:
import Es6Promise from 'es6-promise'; Es6Promise.polyfill(); // or import 'es6-promise/auto'; // or import Promise from 'promise-polyfill'; if (!window.Promise) { window.Promise = Promise; } // or ...
If you want to use import
with Babel, you'll need to install/add the syntax-dynamic-import
plugin while it's still Stage 3 to get around the parser error. When the proposal is added to the spec this won't be necessary anymore.
npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-import babel-preset-es2015 # for this example npm install --save moment
index-es2015.js
function determineDate() { import('moment') .then(moment => moment().format('LLLL')) .then(str => console.log(str)) .catch(err => console.log('Failed to load moment', err)); } determineDate();
webpack.config.js
module.exports = { entry: './index-es2015.js', output: { filename: 'dist.js', }, module: { rules: [{ test: /\.js$/, exclude: /(node_modules)/, use: [{ loader: 'babel-loader', options: { presets: [['es2015', {modules: false}]], plugins: ['syntax-dynamic-import'] } }] }] } };
Not using the syntax-dynamic-import
plugin will fail the build with
Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level
, orModule build failed: SyntaxError: Unexpected token, expected {
async
/await
To use ES2017 async
/await
with import()
:
npm install --save-dev babel-plugin-transform-async-to-generator babel-plugin-transform-regenerator babel-plugin-transform-runtime
index-es2017.js
async function determineDate() { const moment = await import('moment'); return moment().format('LLLL'); } determineDate().then(str => console.log(str));
webpack.config.js
module.exports = { entry: './index-es2017.js', output: { filename: 'dist.js', }, module: { rules: [{ test: /\.js$/, exclude: /(node_modules)/, use: [{ loader: 'babel-loader', options: { presets: [['es2015', {modules: false}]], plugins: [ 'syntax-dynamic-import', 'transform-async-to-generator', 'transform-regenerator', 'transform-runtime' ] } }] }] } };
import
supersedes require.ensure
?Good news: Failure to load a chunk can be handled now because they are Promise
based.
Caveat: require.ensure
allows for easy chunk naming with the optional third argument, but import
API doesn't offer that capability yet. If you want to keep that functionality, you can continue using require.ensure
.
require.ensure([], function(require) { var foo = require("./module"); }, "custom-chunk-name");
System.import
is deprecatedThe use of System.import
in webpack did not fit the proposed spec, so it was deprecated in v2.1.0-beta.28 in favor of import()
.
© 2012–2016 Tobias Koppers
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/guides/code-splitting-import/