• webpack之import 异步import


    模块标准: CommonJS、AMD、CMD、ES6 Module

    CommonJS是Node.js原生支持的模块标准. 使用module.exports和require()函数.
    AMD和CMD比较相似, AMD的实现有require.js, CMD的实现有Sea.js.
    ES6 Module引入importexport两个关键字, 是Webpack推荐的模块标准.

    export 与 import

    export

    首先module.exports = ...export关键字不能混用, 在Wbpack中优先使用export关键字.
    export对一个Module对象进行操作, 而不是普通的js对象, 最后module.exports赋值为该对象以导出.
    使用ES6语法导出的是一个Module对象, 根据default字段, 有"默认导入"和"具名导出"两种说法.

    let value = 88;
    let value2 = 66;
    
    function printValue() {
        console.log(value);
    }
    
    // 导出"默认"变量作为一个{}对象
    export default {
        value2: value, // 导出变量的同时重命名
        printValue,
    };
    // export default value; // 也可以将"默认"变量导出为一个变量或函数, 但不能多次导出"默认"变量
    // export default value2 = value; // 重命名
    
    // 具名导出
    export { value as value2, value2 as value }; // 导出多个非默认变量, 同时重命名别名
    // export { value: value2, value2: value }; // 语法错误
    export var foo = printValue; // 导出单个非默认变量, 同时重命名
    console.log({ foo }); // 现在 foo 是合法变量
    

    import

    import会判断对应模块入口文件(通常是/index.js)中module.exports是普通js对象还是Module对象, 从而实现兼容:

    如果是Module对象, 则有默认导出和其它导出(具名导出)之分
    如果是普通js对象, 那么module.exports就是默认导出

    import * as A from './test'; // 等价于C, 这种语法通常在使用import关键字引用浏览器和服务器通用模块时使用, 因为这些模块不导出Module对象
    import B from './test'; // 默认导入
    const C = require('./test'); // Node.js原始require语法, 可理解为伪代码: C = test.module.exports;
    console.log({ A });
    console.log({ B });
    console.log({ C });
    
    // 更新
    import { default as D } from './test'; // 等价于B
    


    高阶用法

    集线器

    可以将一个js文件作为路由集线器, 导入其它js的非默认同时导出:

    export { DefaultLoadingManager, LoadingManager } from './loaders/LoadingManager.js';
    

    我们将之前的文件命名为test2.js, 在test1.js中路由:

    export { default } from './test2'; // 导出default
    export { foo } from './test2'; // 导出非默认变量foo
    export * from './test2'; // 导出全部非默认变量. 也就是说导出不会包含含default字段
    
    // 也就是说, 导出test2全部可导成员需要以下两步
    export * from './test2';
    export { default } from './test2';
    
    // 有时我们需要导入默认导出, 又需要导入普通的CommonJS导出, 可以这样写:
    import React, { Component } from 'react';
    // 那么之前的导出全部成员可以这么写吗? (疑问)
    export *, { default } from './test2';
    // 导入这样写可以吗? (疑问) 不可以!!!
    import * as React, { Component } from 'react';
    

    构建通用包时, 建议不使用ES6模块

    以下四种React的引入是一样的,显然react包没有使用ES6模块:

    import ReactA, { createElement as e, default as ReactB } from 'react';
    import * as ReactC from 'react';
    const ReactD = require('react');
    console.log(ReactA === ReactB); // true
    console.log(ReactA === ReactC);
    console.log(ReactA === ReactD);
    

    import一个目录

    当我们导入一个目录时, 会尝试执行该目录下的index.js文件. 并且目录优先于同名的js文件, 除非导入时显式指定.js后缀.
    在Windows下文件名不区分大小写, 所以Index.js也可以编译, 但是在Linux下就完蛋了...!这也算是一个坑吧

    异步import

    function(string loader_and_file): Promise
    

    动态加载模块。调用 import() 之处被视为分割点,意思着被请求的模块和它引用的所有子模块,会分割到一个单独的 chunk 中。
    异步import, 模块的处理过程将作为一个分割点单独打包为独立模块, 再通过ajax请求, 请求路径是相对于引用脚本的URL, 所以对于单页应用来说没有问题.

    // "."表示当前js文件, 使用raw-loader异步加载当前js文件的文本内容
    import('!raw-loader!.').then(({ default: text }) => {
        this.setState({ code: text });
    });
    

    非入口点文件

    通过异步import打包后的文件称为非入口点文件, 文件名可以通过Webpack配置中的config.output.chunkFilename确定:

        output: {
            filename: '[name].js',
            path: DIR_DIST,
            chunkFilename: 'async/[id].js', // 此选项确定非入口块文件的名称
        },
    

    Magic Comments可以通过js注释的方式控制每一个异步import.

    官方文档

    https://webpack.docschina.org/api/module-methods/
    异步import及其魔法注释
    https://webpack.js.org/api/module-methods/#magic-comments

    END

  • 相关阅读:
    千万级规模高性能、高并发的网络架构经验分享
    CPU高问题排查
    Worker+MQ解惑
    HashMap解惑
    配置时间同步时,遇到同步无法成功的解决方法
    Django基础—— 1.WEB框架介绍
    html5兼容性问题
    jQuery基础——节点操作
    jQuery基础——基本操作
    jQuery基础——选择器
  • 原文地址:https://www.cnblogs.com/develon/p/13560949.html
Copyright © 2020-2023  润新知