webpack学习(一) — 基础配置
一.了解什么是Webpack?Webpack的作用是什么?
Webpack
是一种端资源构建工具,一个静态模块打包器
。
Webpack的作用就是将在node中写好的代码(后端)解析为在浏览器(前端)可以运行的代码,提高了项目效率和可维护性
。
二.Webpack的5个核心概念
1. entry入口
入口指示Webpack以哪个入口文件开始打包,分析构建内部依赖图
2. output输出
输出指示Webpack打包后的资源bundlex输出到哪里,以及如何命名
3. loader(翻译官的作用)
loader可以让webpack能够处理哪些非js文件(webpack自身只理解js,json,线wenpack5可以处理图片资源)
4. plugins
插件plugins可以用于执行范围更广的任务。插件的范围包括:从打包优化和压缩,一直到重新定义环境中的变量。
5. mode
模块知识Webpack使用相应模式的配置。
1 | /* |
三.搭建webpack的基础配置
- 安装依赖:———–
npm init
- 安装webpack
- 自从有了webpack4之后如果想要使用webpack必须要安装webpack-cli,-D代表实在开发环境中
- 安装
npm install webpack webpack-cli -D
- 创建src文件夹,里面创建入口文件main.js编辑需要的内容
- 利用webpack对内容进行打包
- 在最外层(src的同级目录)创建webpack.config.js文件(文件名称不可更改)
- webpack.config.js文件内容:
1 | //引入path 导入node.js 中专门操作路径模块 |
3. 因为初始配置的时候已经安装了webpack,这时你可以在node-modules/.bin文件夹中发现webpack文件夹所以这个时候再次利用webpack只需要在控制台输入`npx webpack`指令就会去bin文件中寻找webpack.
4. 注意上方代码可能会报错:Module not found: Error: Can't resolve './src' in 'D:\Study\Webpack\01-source-map'这是因为新版的webpack比旧版的更加严格,他一般认为index.html或index.js是入口文件,把main改成index即可。
四.source-map(编译后源文件的映射即编译后的代码)
认识source-map
a.代码通常运行在浏览器上时,是通过**打包压缩**的:
- 这也就表明了真实跑在浏览器上的代码和我们编写的代码是有差异的;
- 比如ES6的代码可能被转化成ES5
- 比如对应的代码行号,列号在经过编译后肯定不会一致
- 比如代码进行丑化压缩时,会将编码名称等修改
- 比如我们使用了TypeScript等方式编写的代码,最终回转换成JS
b.但是,当代码报错需要调试时,调试转换后的代码时很困难的。
c.那么如何可以调试这种转换后不一致的代码呢?答案是source-map
- source-map是从已转换的代码映射到原始的源文件
- 使浏览器可以重构原始源并在调试器中显示重建的原始源
如何使用source-map?
可以分为以下两个步骤;
- 第一步:根据源文件,生成source-map文件,webpack在打包的时候,可以配置生成source-map(即在配置文件中加入;devtool: ‘选定的值’)。配置代码如下:
1 | const path = require("path"); //引入path |
- 第二步:在转换后的代码,最后添加一个注释,它指向sourcemap; 一般在转换后的代码中会自动生成:如下代码:
1 | //即上方提到的注释bundle.js文件名字 |
source-map的好处:
浏览器会根据我们的注释查找相应的source-map,并且根据source-map还原我们的代码,方便调试。
在Chrome中打开控制台,选择设置,按照如下方式打开source-map:
生成source-map文件
- 如何在使用webpack打包的时候,生成对应的source-map?
- webpack为我们提供了非常多的选项(目前是26个),来处理source-map
- 官方文档:https://www.webpackjs.com/configuration/devtool/
- 选择不同的值,生成的source-map会稍微有差异,打包过程也会有差异,可能根据不同的情况进行选择;
- 下面几个值不会生成source-map
- false:不适用source-map,也就是没有任何和source-map相关的内容
- none:production模式下的默认值(什么值都不写),不生成source-map。
- eval:development模式下的默认值,不生成source-map
- 但是它会在eval执行的代码中,添加//#sourceURL=
- 它会被浏览器在执行时解析,并且调试面板中生成对应的一些文件目录,方便我们调试
- 生成source-map
- source-map:生成一个独立的source-map文件,并在bundle文件中有一个注释指向source-map文件
其他类型的值了解即可
五.深入解析Babel-polyfill
什么是Babel?
- Babel是一个工具链,主要用于旧浏览器或者环境中将ECMAScript 2015+代码转换为向后兼容版本的js
- 包括:语法转换,源代码转换,Polyfil实现目标环境缺少的功能等。
Babel命令执行
- babel本身可以作为一个独立的工具(和postcss一样),不和webpack等构建工具配置单独使用。
- 如果希望在命令行尝试使用babel,需要安装如下库:
@babel/core
:babel的核心代码,必须安装
- @babel/cli:可以让我们在命令行中使用babel;
安装指令:npm install @babel/cli @babel/core
- 使用babel处理所写的源代码:
- src:源文件的目录
- –out-dir:指定要输出的文件夹dist;
处理指令:npx babel src --out-dir dist
- 插件安装:
- 如果需要转换箭头函数,则要安装使用箭头函数转换相关的插件:
1 | 安装插件指令:npm install @babel/plugin-transform-arrow-functions -D |
转换源代码(并转换里面的箭头函数):
1 | npx babel ./src --out-dir ./build --plugins=@babel/plugin-transform-arrow-functions |
- 如果需要转换块级作用域(即将const,let转换成var),则要安装转换块级作用域相关的插件:
安装插件指令:
1 | npm install @babel/plugin-transform-block-scoping -D |
转换源代码(并转换里面的箭头函数和块级作用域):
1 | npx babel ./src --out-dir ./build --plugins=@babel/plugin-transform-block-scoping,@babel/plugin-transform-arrow-functions |
Babel的预设preset
- 当转换的内容过多的时候,一个个设置比较麻烦,因此可以使用预设(preset)减少步骤
- 安装@babel/preset-env预设:
1 | npm install @babel/preset-env -D |
- 执行下方命令生成对应文件:
1 | npx babel ./src --out-dir ./bulid --presets=@babel/preset-env |
Babel的底层原理(较为重要)
Babel拥有编译器的工作流程:
- 解析阶段(Parsing)
- 转换阶段(Transfromation)
- 生成阶段(Code Generation)
浏览器兼容性配置
要想实现浏览器的兼容性需要借助Browserslist
Browserslist是什么?Browserslist是一个在不同的前端工具之间,共享目标浏览器和Node.js版本的配置
- Autoprefixer
- Babel
- postcss-preset-env
- eslint-plugin-compat
- stylelint-no-unsupported-broewr-features
- postcss-normailze
- obsolete-webpack-plugin
配置browserlist
- 如何配置browerlist?
- 方案一:在package.json中配置
- 方案二:单独的一个配置文件.browserslistrc
- 方案一:package.json配置:
1 | "browerslist":[ |
- 方案二:.browerslistrc文件:
1 | > 0.5% |
根据上方条件找到符合情况的所有浏览器,根据浏览器的特性对需要转换打包的代码进行适当的调整。
设置目标浏览器的browserlist
最终打包的js文件需要跑在目标浏览器上,那么如何告知babel目标浏览器是什么?
- 方式一:借助browserslist工具
- 方式二:target属性
1 | module: { |
如果两个同时配置产生的效果:
- 配置的targets属性会覆盖browerslist;
- 但是在 开发过程中,更推荐通过browerslist来配置,因为类似于postcss工具,也会使用broesersliat,进行统一浏览器的适配。
babel的配置文件
- 与大多数配置文件一样,babel的配置信息也可以单独的放在一个独立的文件中。因此,babel给我们提供了两种配置文件的编号:
- babel.config.json(后缀.json也可以 改成.js,.cjs,.mjs)文件;
- .babelrc.json(后缀.json也可以改成.js,.cjs,.mjs,作者直接写成.babelrc)文件
- 例子:
1 | //相当于以前的webpack.config.js中的options里的内容,将其babel配置单独拿出,比较好管理 |
- 上方两种方式的区别?目前很多项目都采用了多包管理的方式(babel本身,element-plus,umi等);
- babel.config.json(babel17):可以直接作用域Monorepos项目的子包,更加推荐;
- .babelrc.json:早期使用较多的配置方式,但是对配置Monorepros项目是比较麻烦的;
babel和polyfill
polyfill
- 安装可以使用polyfill插件
1 | npm install core-js regenerator-runtime |
- 在babel.config.js中进行相关配置
1 | //相当于以前的webpack.config.js中的options里的内容,将其babel配置单独拿出,比较好管理 |
注意:当useBuiltIns为false时,corejs需要注释,否则会在控制台提出如下警告:
虽然它有三个值可以设置但是尽量使用usage
React和TS解析
一.如何对React进行打包?
- 首先在src下创建存放react组件的文件夹,在里面写react的jsx形式的组件文件
- 在入口的index.js中引入react组件并进行编写:
1 | //引入react组件 |
创建react文件前需要先安装react插件
1 | npm install react react-dom |
因为以前的配置只是关于js的,React作用的html文件并未对其进行打包,所以要进行html打包的配置
- react所需的html打包的配置
- 安装html打包的库
1 | npm install html-webpack-plugin -D |
- 在webpack.config.js文件中配置html打包所需代码,这样以后只需要用
npm run build
也可以生成html的打包文件
1 | //html打包所引入的库 |
- 因为要转换react代码所以需要安装react的预设:
1 | npm install @babel/preset-react -D |
相关配置:
1 | //相当于以前的webpack.config.js中的options里的内容,将其babel配置单独拿出,比较好管理 |
二.ts编译打包
方式一:
- 首先在src下创建存放ts文件的文件夹,在里面写.ts形式的文件
- 在入口的index.js中引入ts文件并进行编写:
例如:
1 | import {sum} from './ts/math.ts' |
3.转换ts:
首先安装ts相关的转换库让其代码在打包时可以转换成js代码:
1 | npm install ts-loader -D |
其次配置ts-loader:
1 | const HtmlWebpackPlugin = require("html-webpack-plugin"); |
最后进行打包
1 | npm run build |
在下方中安装ts-loader时就会自动安装上方的ts
除了可以用上方的方式编译ts文件之外也可以用下面的方式。它主要是借用babel。
方式二:
1.因为在ts文件中可能含有es语言之类的新语法,浏览器可能不认识,所以需要对其进行补丁。如果单纯的借助上方方式并不能实现,需要在babel对ts进行预设,并且转换。
1 | export function sum(num1: number, num2: number) { |
2.将webpack.config中的use的值设置为”babel-loader”
1 | //解析ts |
3.安装ts的预设
1 | npm install @babel/preset-typescript -D |
4.在babel.config.js中配置ts的预设和补丁,进行方法填充
1 | //ts转换的预设 |
ts-loader与babel-loader的区别:
如何在使用Babel的时候也对ts进行实时监听:
package.json中的script的代码:
1 | "scripts": { |