07-webpack内置js_loader

87 阅读2分钟

全局导出和全局导入

Modular Progress

模块化编程:Modules

简单列举一下,webpack直接支持的模块化:

  • ECMAScript(简称ES Module)
  • AMD
  • CommonJS
  • WebAssembly
  • Asset 资源模块

webpack在配置loader的时候可以配置对应的type,来告诉webpack这个资源改用那种模块解析方式来处理.

常见的可能遇到的问题就是:

  • 前一个loader是ESM模块化处理的,但是后一个loader是CommonJS模块化,所有后面的loader可能无法理解之前的loader的结果代码而导致保存。典型的例子就是 配置 html-loader 和 css-loader 冲突了(当然,最新版本已经没有这个问题了)rule-type

  • ESM是可用做静态分析的,在webpack的tree-shaking是非常有用的,或者基于其它场景下,你需要把一些代码最后指定以 ESM 的方式输出的话,需要考虑如何输出

imports-loader

imports-loader

webpack能够处理js和json,它将这部分的能力封装起来到 imports-loader 和 exports-loader 里面。

imports-loader 处理js模块化的this存在问题,它并不指向全局window而是当前模块本身。如果你需要将它指向window需要做出一定的配置:

let loaders = [
  ...loaders,
  {
     test: require.resolve('./src/test-jquery'),
     use: 'imports-loader?wrapper=window' // 这样的话,模块化该文件的时候,this指向window
    //  use: { 也可以这么写
    //    loader: 'imports-loader',
    //    options: {
    //      wrapper: 'window',
    //      type: // 自定义用何种模块规范来解析
    //    }
    //  }
  }
]
// 建议你看一下打包之后的代码,就知道webpack是做了什么处理的:打包模块输出的func.call(window)

exports-loader

exports-loader

上节的预置依赖全局变量是通过 ProvidePlugin ,webpack解析到预设字符加载模块并替换变量,其实 exports-loader也是可以做到的。

let loaders = [
  ...loaders,
  {
    test: require.resolve('./src/test-foo'),
    loader: "exports-loader",
    options: {
      type: "commonjs",
      exports: "foo", // 相当于导出该文件的 Foo 变量 <=> export { foo }
    },
  },
]

exports-loader的原理其实就是对文件预编译,然后再末尾添加对应的 导出行:

// xxx
export { foo } // +++

因此即使test-foo文件:

// test-jquery
const foo = '这是foo变量'

// index.js
import {foo} from './foo.js'
console.log(foo) // 这是Foo变量

Target

targets

webpack是一个资源打包工具,那么自然的不仅仅可以打包浏览器环境的资源,对于node.js也可以完美的允许。

当然webpack默认是直接转成web段的代码,如果你需要直接的支持转成node端的代码,可以设置:

const target = 'node'

module.exports = {
  target
}