zoukankan      html  css  js  c++  java
  • 模块导入导出

    • bundle 是入口 js,也就是你的 html 会直接引用的 js 文件。
    • chunk 是webpack依据依赖打包的懒加载js文件,我们不会直接引用,一般都是 webpack 自动加载。

    导出

    ES6

    • export
    // 具名导出
    export var Count = 5;
    export function Multiply(a, b) {
      return a * b;
    }
    
    // 默认导出
    export default {
      // Some data...
    };
    
    // 直接从另一个文件导出
    export * from './src/echarts';
    export { default as IhrMore } from '@/components/common/more/more.vue'
    

    CommonJS

    • module.exports调用者通过 require 对模块进行调用时返回的值(默认为一个新对象)。
    module.exports = function (source, map) {
        this.callback(
            null,
            `export default function (Component) {
                Component.options.__docs = ${
                    JSON.stringify(source)
                }
            }`,
            map
        )
    }
    

    AMD

    • define(不能在异步函数中调用?)
    define([name: String], [dependencies: String[]], factoryMethod: function(...))
    define(value: !Function)
    

    webpack 内置的 LabeledModulesPlugin 插件特殊导出导入方式

    • export 标记可以出现在函数声明或变量声明之前。函数名或变量名是导出值的标识符。以异步的方式使用,可能不会达到预期的效果。
    export: var answer = 42;
    export: function method(value) {
      // 做一些操作……
    };
    
    • 使当前作用域下,可访问所依赖模块的所有导出。require 标签可以放置在一个字符串之前。依赖模块必须使用 export 标签导出值。CommonJS 或 AMD 模块无法通过这种方式,使用标签模块的导出。
    // some-dependency.js使用export导出
    export: var answer = 42;
    export: function method(value) {
      // 执行一些操作……
    };
    
    // 其他模块使用require:导入
    require: 'some-dependency';
    console.log(answer);
    method(...);
    

    同步导入

    ES6

    • import
    import MyModule from './my-module.js';
    import { NamedExport } from './other-module.js';
    

    CommonJS

    • 以同步的方式检索其他模块的导出。var myModule = require('my-module');
    • 以同步的方式获取模块的 ID。require.resolve('dependency')由编译器(compiler)来确保依赖项在最终输出 bundle 中可用。(虽然返回的是模块ID但实际上指向的模块已经被加载到当前模块内了)
      • webpack 中模块 ID 是一个数字(而在 NodeJS 中是一个字符串 -- 也就是文件名)。
    • 多处引用同一个模块,最终只会产生一次模块执行和一次导出,所以提供了这个接口以获取模块缓存。require.cache[require.resolve('dependency')];
    • 删除模块。delete require.cache[require.resolve('dependency')];

    Webpack

    • require.context程序化的定义导入,能够实现批量导入。返回一个require 函数,该函数有三个属性:resolve 、keys、id(这个require 函数并不是CommonJS中的require函数)
      • resolve: 是一个函数,他返回的是被解析模块的id
      • keys: 是一个函数,他返回的是一个数组,该数组是由所有可能被上下文模块解析的请求对象组成(由文件名字符串组成的数组)
      • id:上下文模块的id(?)
      • 该require 函数传入keys返回的数组中的文件名时,返回组件的配置信息
    // 语法
    require.context(
      directory: String,    // 其组件目录的相对路径
      includeSubdirs: Boolean    // 是否查询其子目录 /* 可选的,默认值是 true */,
      filter: RegExp    // 匹配基础组件文件名的正则表达式 /* 可选的 */
    )
    
    // 例如
    import BaseButton from './components/BaseButton.vue'
    import BaseIcon from './components/BaseIcon.vue'
    import BaseInput from './components/BaseInput.vue'
    // 可写为
    const requireComponent = require.context(
      './components',    // 其组件目录的相对路径
      false,    // 是否查询其子目录
      /Base[A-Z]\w+\.(vue|js)$/    // 匹配基础组件文件名的正则表达式
    )
    
    // require.context返回一个函数requireComponent(fileName)
    // 猜测该函数可以传入一个参数,该参数为正则匹配值去掉后缀后的字符串,返回导入的模块
    // require.contex和resolve不同的是区分export default和export(resolve是指哪个?)
    requireComponent.keys().forEach(fileName => { // keys是一个函数,他返回的是一个数组,该数组是由所有可能被上下文模块解析的请求对象组成(由文件名字符串组成的数组)
      const componentConfig = requireComponent(fileName)    // 获取组件配置
      // 获取组件的 PascalCase 命名
      const componentName = upperFirst( // lodash中的方法,转化字符串的首字母为大写
        camelCase( // lodash中的方法,把字符串转为首字母为小写的驼峰式
          // 剥去文件名开头的 `./` 和结尾的扩展名
          fileName.replace(/^\.\/(.*)\.\w+$/, '$1')    //匹配 ./ 和 .[a-zA-Z_] 结尾之间的所有值,'$1'是replace的用法:使用字符串作为参数,'$1'代表第 1 个括号匹配的字符串替换匹配到的值
        )
      )
    
      // 全局注册组件
      Vue.component(
        componentName,
        // 如果这个组件选项是通过 `export default` 导出的,
        // 那么就会优先使用 `.default`,
        // 否则回退到使用模块的根。
        componentConfig.default || componentConfig
      )
    })
    
    
    // require.context返回一个函数,拥有方法resolve用以返回引入的模块的id,猜测参数为正则匹配值去掉后缀
    var context = require.context('components', true, /\.html$/);
    var componentA = context.resolve('componentA');
    
    • require.resolveWeak不会将 module 引入到 bundle 中。这就是所谓的"弱(weak)"依赖。(作为辅助打包的条件,还可用于服务端渲染SSR?)
    if(__webpack_modules__[require.resolveWeak('module')]) {
      // 模块可用时,执行一些操作……
    }
    if(require.cache[require.resolveWeak('module')]) {
      // 在模块被加载之前,执行一些操作……
    }
    
    // 你可以像执行其他 require/import 方法一样,
    // 执行动态解析(“上下文”)。
    const page = 'Foo';
    __webpack_modules__[require.resolveWeak(`./page/${page}`)];
    

    异步导入

    ES6

    • import 规范不允许控制模块的名称或其他属性,因为 "chunks" 只是 webpack 中的一个概念。幸运的是,webpack 中可以通过注释接收一些特殊的参数,而无须破坏规定:
    • webpackInclude:在导入解析(import resolution)过程中,用于匹配的正则表达式。只有匹配到的模块才会被打包(仅文件名)。
    • webpackExclude:在导入解析(import resolution)过程中,用于匹配的正则表达式。所有匹配到的模块都不会被打包(仅文件名)。
    • webpackChunkName:新 chunk 的名称。从 webpack 2.6.0 开始,[index] and [request] 占位符,分别支持赋予一个递增的数字和实际解析的文件名。
    • webpackMode:从 webpack 2.6.0 开始,可以指定以不同的模式解析动态导入。
      • "lazy"(默认):为每个 import() 导入的模块,生成一个可延迟加载(lazy-loadable) chunk。
      • "lazy-once":生成一个可以满足所有 import() 调用的单个可延迟加载(lazy-loadable) chunk。(这种模式仅在部分动态语句中有意义,例如 import(./locales/${language}.json),其中可能含有多个被请求的模块路径。)
      • "eager":不会生成额外的 chunk,所有模块都被当前 chunk 引入,并且没有额外的网络请求。仍然会返回 Promise,但是是 resolved 状态。和静态导入相对比,在调用 import()完成之前,该模块不会被执行。
      • "weak":尝试加载模块,返回 Promise,但是只有在客户端上已经有该 chunk 时才成功解析。如果该模块不可用,Promise 将会是 rejected 状态,并且网络请求永远不会执行。
    • ./locale/${language}至少需要一些文件的路径信息,webpack打包时会把所有./locale/都打包到一个chunk下
    // 单个目标
    import(
      /* webpackChunkName: "my-chunk-name" */
      /* webpackMode: "lazy" */
      'module'
    );
    
    // 多个可能目标
    import(
      /* webpackInclude: /\.json$/ */
      /* webpackExclude: /\.noimport\.json$/ */
      /* webpackChunkName: "my-chunk-name" */
      /* webpackMode: "lazy" */
      `./locale/${language}`
    );
    

    CommonJS

    • require.ensure
    require.ensure(
      dependencies: String[], // 字符串构成的数组,声明 callback 回调函数中所需的所有模块。
      // 只要加载好全部依赖,webpack 就会执行此函数。
      // require 函数的实现,作为参数传入此函数。当程序运行需要依赖时,可以使用 require() 来加载依赖。函数体可以使用此参数,来进一步执行 require() 模块。这里的参数require必须为该名称才能保证被webpack解析
      callback: function(require), 
      errorCallback: function(error), 
      chunkName: String // 建出的 chunk 的名字。通过将同一个 chunkName 传递给不同的 require.ensure() 调用,我们可以将它们的代码合并到一个单独的 chunk 中,从而只产生一个浏览器必须加载的 bundle。
    )
    

    AMD

    • requirerequire(dependencies: String[], [callback: function(...)])

    Webpack

    • require.include引入一个不需要执行的依赖,这可以用于优化输出 chunk 中的依赖模块的位置。
    equire.include('a');
    require.ensure(['a', 'b'], function(require) { /* ... */ });
    require.ensure(['a', 'c'], function(require) { /* ... */ });
    
    // 这会产生以下输出:
    // entry chunk: file.js and a
    // anonymous chunk: b
    // anonymous chunk: c
    // 如果不使用 require.include('a'),输出的两个匿名 chunk 都有模块 a。
    

    CSS 模块化导入使用方法

    • import cssName frome 'cssUrl'
      • 在 JavaScript 中作为 CSS Modules 导入 CSS 或其它预处理文件,该文件应该以 .module.(css|less|sass|scss|styl) 结尾
      • 不能配合使用Scope CSS ?
      • 只是一个模块化处理入口,返回一个空对象
      • 不使用 CSS Modules 应该也可以直接使用预处理器语言
    • @import url("fineprint.css");具体使用方法,似乎是在style中引入css的方法
      • @import "@/variables.scss"; 在vue.config.js中存在,?
    • link 标签引入在项目中会被作为模块处理?
  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/qq3279338858/p/9875995.html
Copyright © 2011-2022 走看看