Code Splitting - Using import()

Dynamic import

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 that import() 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')).

Promise polyfill

import() relies on Promise internally.

If you useimport() 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 ...

Usage with Babel

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
    or
  • Module build failed: SyntaxError: Unexpected token, expected {

Usage with Babel and 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 deprecated

The 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()
.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容