模块化开发

模块化概述

项目越来越复杂,需要大量的时间维护,模块化是通过把复杂代码,按照功能的不同,划分为不同的模块,单独维护的一种方式,去提高我们的开发效率,降低维护成本。
【模块化】只是思想,并不包含具体的实现

模块化演变过程

  • 文件划分方式:文件即模块,会污染全局作用域,完全依靠约定
  • 命名空间方式
  • IIFE:立即执行函数,实现了私有成员

模块化规范的出现

commonJS规范:以同步方式加载模块

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

AMD:异步

  • 目前绝大多数第三方库都支持AMD规范
  • 使用起来相对复杂
  • 模块JS文件请求频繁

    模块化标准规范

  • node:commonJS

  • 浏览器:ES Modules

ES Modules 特性

  • 自动采用严格模式,忽略 use strict
  • 每个ES Modules都是运行在单独的私有作用域中
  • 在ES Modules当中,外部JS文件是通过CORS的方式去请求的
  • 在ES Modules的script标签会延迟执行脚本

ES Module 导入导出的注意事项

  • 导出成员并不是一个自变量对象,导出的对象并不是成员里的值,导出的是地址存储的值
  • 导入并非解构,导入成员是只读的
  • 导入导出有固定的语法

ES Module 导入用法

导入时不能是扩展名,可以是相对路径的点斜线文件,或者是绝对路径,再或者是完整的URL

ES Module 导出导入成员

导入的结果直接作为当前文件的导出成员

ES Modules in Node.js - 与 CommonJS

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

ES Modules in Node.js - 新版本进一步支持

  1. // package.json
  2. {
  3. "type": "module"
  4. }

ES Modules in Node.js - Babel 兼容方案

image.png

  1. {
  2. // "presets": [ "@babel/preset-env" ],
  3. "plugins": [
  4. "@babel/plugin-transform-modules-commonjs"
  5. ]
  6. }

Webpack 打包

模块化打包工具的由来

模块化存在的问题:

  • ES Modules 存在环境兼容问题
  • 模块文件过多,网络请求频繁
  • 所有的前端资源都需要模块化
  • 毋庸置疑,所有文件都需要模块化

需要:

  • 新特性代码编译
  • 模块化JavaScript打包
  • 支持不同类型的资源模块

模块打包工具概要

webpack

  • 模块打包器(Module Builder)
  • 代码拆分(Code Splitting)
  • 资源模块(Asset Module)

模块化工具的作用:打包工具解决的是前端整体的模块化,并不单指JavaScript模块化

Webpack:大而全,适合开发应用程序

概念:
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle,
配置文件的核心概念:

  • 入口(entry):告诉webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
  • 输出(output):告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。
    • filename:设置输出文件的文件名
    • path: 指定filename所在的目录
  • loader:让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
    • test 属性,识别出哪些文件会被转换。
    • use 属性,定义出在进行转换时,应该使用哪个 loader。
  • 插件(plugins):打包优化,资源管理,注入环境变量。
  • 模式(mode):通过选择 development, production 或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production。
  • 浏览器兼容性(browser compatibility):webpack 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)。webpack 的 import() 和 require.ensure() 需要 Promise。不支持旧版本浏览器

JavaScript驱动了整个前端应用

  • 逻辑合理,JS确实需要这些资源文件
  • 确保上线资源不缺失,都是必要的

webpack模块加载方式

  • 遵循ES Modules标准的import声明
  • 遵循CommonJS标准的require函数
  • 遵循AMD标准的define函数和require函数


其他文件触发加载**

  • 样式代码中的@import指令和url函数
  • HTML代码中图片标签的src属性

    其他打包工具

    Rollup:小而美,适合开发库/框架

    更为小巧,仅仅是一款ES Module打包器,充分利用ESM各项特性的高效打包器,插件是rollup唯一的扩展途径

优点:

  • 输出结果更加扁平,执行效率更高
  • 自动移除未引用代码
  • 打包结果依然完全可读

缺点:

  • 加载费ESM的第三方模块比较复杂
  • 模块最终都被打包倒一个函数中,无法实现HMR
  • 浏览器环境中,代码拆分功能依赖AMD库
  1. // rollup.config.js
  2. import json from 'rollup-plugin-json'
  3. import resolve from 'rollup-plugin-node-resolve'
  4. import commonjs from 'rollup-plugin-commonjs'
  5. export default {
  6. input: {
  7. index: 'src/index.js'
  8. },
  9. // output: {
  10. // file: 'dist/bundle.js',
  11. // format: 'iife'
  12. // },
  13. output: {
  14. dir: 'dist',
  15. format: 'amd'
  16. },
  17. plugins: [ json(), resolve(), commonjs() ]
  18. }

规范化标准

规范化介绍

规范化介绍

  • 为什么要有规范标准
  • 哪里需要规范化标准
  • 实施规范化的方法

为什么要有规范化标准

  • 软件开发需要多人协同
  • 不同开发者具有不同的编码习惯和喜好
  • 不同的喜好增加项目维护成本
  • 每个项目或者团队需要明确统一的标准

哪里需要规范化标准

  • 代码、文档、甚至是提交日志
  • 开发过程中人为编写的成果物
  • 代码标准化规范最为重要

实施规范化的方法

  • 编码前人为的标准约定
  • 通过工具实现Lint

常见的规范化实现方式

  • ESLint工具使用
  • 定制ESLint校验规则
  • ESLint对TypeScript的支持
  • ESLint结合自动化工具或者Webpack
  • 基于ESLint的衍生工具
  • Stylelint工具的使用

Eslint介绍

  • 最为主流的JavaScript Lint工具监测JS代码质量
  • ESLint很容易统一开发者的编码风格
  • ESLint可以帮助开发者提升编码能力

ESLint 快速上手

ESLint检查步骤

  • 编写“问题”代码
  • 使用eslint执行检测
  • 完成eslint使用配置 eslint --init

.eslintrc.js 中 env 运行环境:环境不互斥

  • browser - 浏览器环境中的全局变量。
  • node - Node.js全局变量和Node . js作用域。
  • commonjs - CommonJS全局变量和CommonJS 作用域(用于Browserify/WebPack 打包的只在浏览器中运行的代码)。
  • shared-node browser - Node. js和Browser 通用全局变量。
  • es6 - 启用除了modules 以外的所有ECMAScript 6特性(该选项会自动设置ecmaVersion 解析器选项为6) 。
  • worker - Web Workers全局变量。
  • amd -将require() 和define() 定义为像amd -样的全局变量。
  • mocha -添加所有的Mocha 测试全局变量。
  • jasmine -添加所有的Jasmine 版本1.3和2.0的测试全局变量。
  • jest -Jest全局变量。
  • phantomjs - PhantomJS 全局变量。
  • protractor - Protractor 全局变量。
  • qunit - QUnit全局变量。
  • jquery - jQuery 全局变量。
  • prototypejs - Prototype.js 全局变量。
  • shelljs - ShelLJS全局变量。
  • meteor - Meteor全局变量。
  • mongo - MongoDB 全局变量。
  • applescript - AppLeScript 全局变量。
  • nashorn - Java 8 Nashorn 全局变量。
  • servic eworker
  • Service Worker 全局变量。
  • atomtest - Atom测试全局变量。
  • embertest - Ember 测试全局变量。
  • webextensions - WebExtensions 全局变量。
  • greasemonkey - GreaseMonkey 全局变量

eslint结合自动化工具的好处:

  • 集成之后,ESLint-定会工作
  • 与项目统一 ,管理更加方便

使用eslint-loader:在babel-loader 之前使用,需要在设置内添加

  1. enforce:'pre'

Git Hooks介绍

  • Git Hook也称之为git钩子,每个钩子都对应一个任务
  • 通过shell脚本可以编写钩子任务触发时要具体执行的操作

作业

一、简答题

1、Webpack 的构建流程主要有哪些环境?如果可以请尽可能详尽的描述 Webpack 打包的整个过程。

mode:

  • development:默认值,启用 NamedChunksPlugin 和 NamedModulesPlugin
  • production:启用 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 TerserPlugin
  • none:不做任何优化

以下来自Webpak官网
概念:
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle,
配置文件的核心概念:

  • 入口(entry):告诉webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
  • 输出(output):告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。
    • filename:设置输出文件的文件名
    • path: 指定filename所在的目录
  • loader:让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
    • test 属性,识别出哪些文件会被转换。
    • use 属性,定义出在进行转换时,应该使用哪个 loader。
  • 插件(plugins):打包优化,资源管理,注入环境变量。
  • 模式(mode):通过选择 development, production 或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production。
  • 浏览器兼容性(browser compatibility):webpack 支持所有符合 ES5 标准 的浏览器(不支持 IE8 及以下版本)。webpack 的 import() 和 require.ensure() 需要 Promise。不支持旧版本浏览器。

2、Loader 和 Plugin 有哪些不同?请描述一下开发 Loader 和 Plugin 的思路。

答:loader负责资源文件从输入到输出的转换,并且对于同一个资源可以一次进行使用多个loader,plugin目的在于解决 loader无法实现的其他事,如:打包优化,资源管理,注入环境变量等。

开发思路:**

  • loader:根据需求对source进行转换,并返回相应的JavaScript代码
  • plugin:通过钩子机制实现,类似于事件,根据所需要实现的功能使用生命周期中的钩子,挂载函数实现扩展。

二、编程题

1、使用 Webpack 实现 Vue 项目打包任务

具体任务及说明:

先下载任务的基础代码:https://github.com/lagoufed/fed-e-001/raw/master/tasks/02-02-base-code.zip

这是一个使用 Vue CLI 创建出来的 Vue 项目基础结构

有所不同的是这里我移除掉了 vue-cli-service(包含 webpack 等工具的黑盒工具)

这里的要求就是直接使用 webpack 以及你所了解的周边工具、Loader、Plugin 还原这个项目的打包任务

尽可能的使用上所有你了解到的功能和特性

作业要求
本次作业的中的编程题要求大家完成相应代码过后,录制一个小视频简单介绍一下实现思路,演示一下相应功能。最终将录制的视频和代码统一提交至作业仓库。