美文网首页
Code Splitting - Using import()

Code Splitting - Using import()

作者: 卢泉威 | 来源:发表于2017-03-19 22:39 被阅读0次

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

    相关文章

      网友评论

          本文标题:Code Splitting - Using import()

          本文链接:https://www.haomeiwen.com/subject/lobvnttx.html