webpack学习笔记
模块化
1)概念
模块化就是把一个复杂的程序按照一定的规则封装成几个块,并组合到一起,模块内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信。
2)模块化规范
CommonJS
1.特点
- Nodejs采用这种方式
- 模块可以多次加载,但只会在第一次加载时运行一次,然后运行结果会被缓存
- 在服务器端模块的加载是运行时同步加载的,在浏览器端模块需要提前编译打包处理
- 模块加载的顺序按照其在代码中出现的顺序
2.基本语法
- 暴露模块:module.exports=value或export.xxx=value
- 引入模块:require(xxx),
AMD
1.特点
- AMD规范可以用于浏览器环境,并且允许非同步加载模块,也可以根据需要动态加载模块
2.基本语法
//定义有依赖的模块
define(['module1','module2'],function(m1,m2){
return 模块
})
//引入使用模块
require(['module1','module2'],function(m1,m2){
使用m1/m2
})
ES6
1.特点
使得编译时就能确定模块的依赖关系以及输入和输出的变量,将逐渐取代其他规范。
2.基本语法
//导入
import { xx } from ' xxx ';
import xx from 'xxx';
//导出
export function hello(){ };
export default {
};
3.ES6与CommonJS的差异
CommonJS模块输出的是一个值的拷贝。ES6模块输出的是值的引用
CommonJS模块是运行时加载,ES6模块是编译时输出接口
webpack概念
webpack可以看作是一个模块打包机bundler,通过分析项目结构找到JavaScript模块以及其他的一些浏览器不能直接运行的拓展语言,并将其打包成合适的格式以供浏览器使用。
为什么要使用webpack?
- JavaScript和css的依赖问题
- 性能优化=》文件合并和文件压缩
- 提高开发效率=》vendor前缀、单元测试、代码分析、版本升级
- 可替代grunt和gulp
webpack的安装与使用
- 安装webpack前要确保系统安装了Node.js,且版本要大于等于5.0.0
npm i -D webpack@<version>
- 在开始给项目加入构建前,需要新建一个web项目 npm init
- 运行webpack:node_modules/.bin/webpack
npm start:webpack --config webpack.config.js
使用Loader
将所有类型的文件转换为webpack能够处理的有效模块(js/json模块),一般以xxx-loader命名
配置里的module.rules数组配置了一组规则,告诉webpack在遇到哪些文件时使用哪些loader去加载和转换
使用Plugin
Plugin 是用来扩展 Webpack 功能的,通过在构建流程里注入钩子实现,它给 Webpack 带来了很大的灵活性。
使用DevServer
npm i-D webpack-dev-server
- 提供http服务
- 实时预览
- 支持Source Map 方便调试
webpack核心概念webpack.config.js
Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
// 类型可以是 string | object | array entry: './app/entry', // 只有1个入口,入口只有1个文件 entry: ['./app/entry1', './app/entry2'], // 只有1个入口,入口有2个文件 entry: { // 有2个入口 a: './app/entry-a', b: ['./app/entry-b1', './app/entry-b2'] },
module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
module: { rules: [ // 配置 Loader { test: /\.jsx?$/, // 正则匹配命中要使用 Loader 的文件 include: [ // 只会命中这里面的文件 path.resolve(__dirname, 'app') ], exclude: [ // 忽略这里面的文件 path.resolve(__dirname, 'app/demo-files') ], use: [ // 使用那些 Loader,有先后次序,从后往前执行 'style-loader', // 直接使用 Loader 的名称 { loader: 'css-loader', options: { // 给 html-loader 传一些参数 } } ] }, ], noParse: [ // 不用解析和处理的模块 /special-library\.js$/ // 用正则匹配 ], },
Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
// 输出文件存放的目录,必须是 string 类型的绝对路径。 path: path.resolve(__dirname, 'dist'), // 输出文件的名称 filename: 'bundle.js', // 完整的名称 filename: '[name].js', // 当配置了多个 entry 时,通过名称模版为不同的 entry 生成不同的文件名称 filename: '[chunkhash].js', // 根据文件内容 hash 值生成文件名称,用于浏览器长时间缓存文件 // 发布到线上的所有资源的 URL 前缀,string 类型 publicPath: '/assets/', // 放到指定目录下 publicPath: '', // 放到根目录下 publicPath: 'https://cdn.example.com/', // 放到 CDN 上去 // 导出库的名称,string 类型 // 不填它时,默认输出格式是匿名的立即执行函数 library: 'MyLibrary', // 导出库的类型,枚举类型,默认是 var // 可以是 umd | umd2 | commonjs2 | commonjs | amd | this | var | assign | window | global | jsonp , libraryTarget: 'umd', // 是否包含有用的文件路径信息到生成的代码里去,boolean 类型 pathinfo: true, // 附加 Chunk 的文件名称 chunkFilename: '[id].js', chunkFilename: '[chunkhash].js', // JSONP 异步加载资源时的回调函数名称,需要和服务端搭配使用 jsonpFunction: 'myWebpackJsonp', // 生成的 Source Map 文件名称 sourceMapFilename: '[file].map', // 浏览器开发者工具里显示的源码模块名称 devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // 异步加载跨域的资源时使用的方式 crossOriginLoading: 'use-credentials', crossOriginLoading: 'anonymous', crossOriginLoading: false,
webpack工作原理概括
运行流程
- 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler。
- 编译:从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理。
- 输出:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统
(Babel:把新的ES6语法用ES5实现,给新的API注入polyfill)