webpack原理与实践笔记

58 阅读3分钟

前置知识

1、commonjs规范:

  • 一个文件就是一个模块
  • 每个模块都有单独的作用域
  • 通过module.exports导出成员
  • 通过require函数载入模块

commonjs以同步方式加载模块。node是启动时加载模块,执行过程中不需要加载;同步方式不适应浏览器,由此出现了require()模块,在浏览器中以异步方式加载模块。

模块化标准规范最佳实践: node.js遵循commonjs规范,浏览器环境遵循ES Module(主流前端模块化规范)规范

2、ES Module特性

  • 自动采用严格模式,忽略'use strict'
  • 每个ESM模块都是单独的私有作用域
  • ESM是通过CORS去请求外部js模块的
  • ESM的script标签会延迟执行脚本
<body>
    <!-- 通过script添加Type = module 的属性,就可以在ES Module的标准执行其中的js代码 -->
    <script type="module">
        console.log("this is module");
    </script>
    <!--1、 ESM 自动采用严格模式 忽略 'use strict' -->
    <!--2、每个ES Module都是运行在单独私有作用域中 -->
    <script type="module">
        var foo = 100
        console.log(100);
    </script>
    <script type="module">
        console.log(foo);//报错
    </script>
    <!-- 3、ESM是通过CORS方式请求外部js模块的 服务端需要支持CORS -->
    <!-- 4、ESM 的script标签会延迟执行脚本  -->
    <script src="demo.js"></script>
    <p>先执行demo.js脚本才会执行这句话</p>

    <script src="demo.js" type="module" ></script>
    <p>我先出现,加了module使用延期执行,先渲染页面再执行脚本</p>
</body>

3、ES Module导入和导出

1export {
    hello as default, //设置成了默认导出成员
    name as fooName
}
import {default as newHollo} from "./module.js"  //导入时必须重命名 default是关键词

2export default hello //将该变量当成默认导出
import abc from './module.js' //默认导出下变量名可任意取

3//export 后面的{}不是对象字面量 而是固定语法
//export 并不是复制值导出去,而是导出的是一个引用,导出的是name、age、hello所在的内存空间所在的引用关系给了引入的文件
export {
    name,hello,age
}
// 使用exprot default 才是对象,后面也可以直接使用变量
export default {name,age}
//import也不是解构而是固定语法 引入的是name和age所在内存空间的引用关系地址 对外暴露的引用关系是只读
import {name,age} from './module.js' 

4、
--import引入时使用完整的文件名称,不要去掉.js;
--使用相对路径时使用./开头,不然有可能当成第三方引入;
--也可以使用绝对路径和完整的url

5、只是需要执行模块不需要提取模块中的成员 可以使用以下两种方法
import {} from './module.js'
import './module.js'

6、全部导入
import * as mod from './module.js'

7、动态导入模块(应用场景:需要某些条件满足过后才导入该模块)
import ('./module.js').then(function (res){
//返回的是一个promise 当模块加载完后自动执行then里面的函数。模块对象可以通过参数res拿到
    console.log(res)
})

8、同时导出命名成员和默认成员,两种方法如下:
import {name,age,default as newName} from "./module.js"
import newName , {name,age} from "./module.js" //逗号左边是默认成员 名字任取

9、直接导出所导入的成员
把import {name,age} from "./module.js"变成export {name,age} from "./module.js"
//注意点:
export {name,age} from "./module.js"
//当前作用域无法访问这些成员
 console.log(name,age);//报错

4、ES Module浏览环境支持及polyfill

//ie不支持es6引入polyfill使其支持es6语法 
<script nomodule src="https://unpkg.com/promise-polyfill@8.2.0/dist/polyfill.min.js"></script>
//引用的是babel及时运行在浏览器的环境的一个版本
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
//引入的是ES Module loader的核心代码  读取该代码交给babel转换时代码正常工作
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
//注意如果支持ES Module的浏览器 还引入有polyfill ES Module会执行两次 可以使用nomodule属性避免,
//加了该属性,支持的则不会再执行polyfill,也就不会重复执行ES Module
//(也就开发阶段玩玩,生产阶段勿cue;该原理时运行阶段动态解析脚本,效率会有所降低;生产阶段需要预先编译出来才行)
<script type="module">
    import { foo } from './module.js'
    console.log(foo)
</script>

5、在node环境中运行ES Module

  • ES Module中可以导入CommonJS模块
  • CommonJS中不能导入ES Module模块
  • CommonJS始终只会导出一个默认成员
  • 注意import不是解构导出对象

更新中...