- 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
- require
require(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 标签引入在项目中会被作为模块处理?
来源:https://www.cnblogs.com/qq3279338858/p/9875995.html