编写的代码 ==》经过打包工具(glup、rollup、webpack、vite)本身也是js代码,读取文件操作的,依赖于 node 环境
= = 》 普通的html 、css 、javascript
= = 》 打包到静态服务器
= = 》 跑在用户的浏览器
const path = require("path");
// 帮助我们从路径当中获取一些信息
const filepath = "C://abc/cba/nba.txt";
// 1. 可以从一个路径中获取一些信息
// 1.1 拿到文件的后缀名
console.log(path.extname(filepath));
// 1.2 获取文件名
console.log(path.basename(filepath));
// 1.3 获取文件夹
console.log(path.dirname(filepath));
const path1 = "/abc/cba";
const path2 = "../../lili/kobe/james.txt";
// 2. 将多个路径拼接在一起
console.log(path.join(path1, path2));
// 3. 将多个路径拼接在一起,最终返回一个绝对路径: path.resolve
console.log("-----resolve------");
// 从右向左依次处理,形成了绝对路径就不会继续往前找了
console.log(path.resolve(path1, path2,"/abc.txt"));
npm i webpack webpack-cli -D
npx webpack
后面可以跟参数webpack.config.js
– webpack 配置文件const path = require("path");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置出口
output: {
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "./build"),
},
};
npm i css-loader -D
module: {
// 规则很多,对应的是数组类型
rules: [
// 数组里面放对象
{
// 告诉webpack 要匹配什么文件
test: /\.css$/,
// 要使用哪些loader
use: [{ loader: "css-loader" }],
},
],
},
npm i style-loader -D
const path = require("path");
module.exports = {
// 配置rukou
entry: "./src/index.js",
// 配置出口
output: {
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "./build"),
},
module: {
// 规则很多,对应的是数组类型
rules: [
// 数组里面放对象
{
// 告诉webpack 要匹配什么文件
test: /\.css$/,
// 要使用哪些loader
use: [{ loader: "style-loader" }, { loader: "css-loader" }],
},
],
},
};
test: /\.css$/,
// 要使用哪些loader
// use: [{ loader: "style-loader" }, { loader: "css-loader" }],
// 简写一:如果 Loader 只有一个
// loader: 'css-loader'
// 简写二:多个loader不需要配置其他options
use: ["style-loader", "css-loader"],
npm i less-loader -D
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
安装:npm i postcss-loader -D
使用:use: ["style-loader", "css-loader", "postcss-loader"]
postcss 介绍
npm i autoprefixer -D
重新配置
{
// 告诉webpack 要匹配什么文件
test: /\.css$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"autoprefixer"
]
},
},
},
],
},
太臭太长了,在项目目录中里面创建文件postcss.config.js
module.exports = {
plugins: ["autoprefixer"],
};
因为有下面这个,所以卸载它:npm uninstall autoprefixer
也可以使用另外的插件postcss-preset-env
:预设环境
npm install postcss-preset-env -D
import 图片名字 from "../img/zznh.png"
npm i file-loader
{
test: /\.(png|jpe?g|svg|gif)$/,
// 当成资源类型
type:"assets"
},
const { type } = require("os");
const path = require("path");
const { webpack } = require("webpack");
module.exports = {
// 配置rukou
entry: "./src/index.js",
// 配置出口
output: {
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "./build"),
// assetModuleFilename: "abc.png",//很少在这配置
},
module: {
// 规则很多,对应的是数组类型
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
{
test: /\.(png|jpe?g|svg|gif)$/,
// 当成资源类型
// type: "asset"
// 1. 打包两张图片,并且这两张图片有自己的地址,将地址设置到img/bgi中
// type:"asset/resource"
// 2. 把图片进行 base64 编码,并且直接将编码后的源码放在打包的js文件中
// type: "asset/inline"
// 合理的规范
// 1 对于小一点的图片,可以进行base64的编码
// 2 对于大一点的图片,单独的图片打包,形成 url 地址,单独的请求这个 url 文件
// 由此诞生了asset
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 60 * 1024,
},
},
// 设置文件名
generator: {
// 一般名字不写死,写上占位符
// name:指向原来的图片名称
// ext(扩展名):直接带点
// hash:webpack生成的hash,只使用前八位
// 放在build的img 文件夹
filename: "img/[name]_[hash:8][ext]",
},
},
],
},
};
npm i babel-loader -D
{
test: /\.js$/,
use: ["babel-loader"],
},
npm i @babel/cli @babel/core -D
babel.config.js
module.exports = {
// plugins: [
// "@babel/transform/"
// ]
presets: ["@babel/preset-env"],
};
npm i @babel/preset-env -D
npm i vue
开发生产都会使用npm i vue-loader -D
{
test: /\.vue$/,
loader:"vue-loader"
}
const { VueLoaderPlugin } = require('vue-loader/dist/index')
const path = require("path");
const { webpack } = require("webpack");
module.exports = {
// 配置rukou
entry: "./src/index.js",
// 配置出口
output: {
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "./build"),
// assetModuleFilename: "abc.png",//很少在这配置
},
module: {
// 规则很多,对应的是数组类型
rules: [
{
test: /\.vue$/,
loader:"vue-loader"
}
],
},
plugins: [
new VueLoaderPlugin()
]
};
用于设置模块如何被解析
webpack 能解析三种文件路径
解析
文件:imprt utils form './utils/format'
js/json
具备扩展名,直接打包文件
否则使用 resolve.extentions 自动添加扩展名
可以自己配置 resolve
resolve: {
// 配置后可省略后缀名
extensions:['.js','.json','.vue','.jsx','.ts','.tsx']
},
文件夹:
alias
resolve: {
// 省略后缀名
extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
// 给文件夹配置别名
alias: {
utils: path.resolve(__dirname, "./src/utils"),
},
},
npm i clean-webpack-plugin -D
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
plugins: [new VueLoaderPlugin(),new CleanWebpackPlugin()],
output: {
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "./build"),
// assetModuleFilename: "abc.png",//很少在这配置
clear: true,
},
在进行项目部署的时,必然也是需要有对应的入口文件 index.html,需要对 index.html 进行打包处理
安装这个插件:npm i html-webpack-plugin -D
build 文件夹下面会自动生成 html 文件
在生成过程会有一个模板,在 html-webpack-plugin 的源码中,有一个 default_index.ejs 模块
也可以自定义模板
const HtmlWebpackPlugin = require("html-webpack-plugin");
plugins: [
new HtmlWebpackPlugin({
title: "实时音频流可视化",
// 自己指定模板
template:'./index.html'
}),
],
webpack 中内置的插件
全局注入变量
默认注入了变量:process.env.NODE_ENV
可以使用 DefinePlugin 中定义的变量
const { DefinePlugin } = require("webpack");
plugins: [
new DefinePlugin({
// 会当成代码去解析,所以需要加引号(eval)
// 前边是变量,随便你加不加引号
BASE_URL: "'./'",
lili: "'lili'",
}),
],
none
| development
|production
mode:production,
npm i webpack-dev-server -D
devServer: {
hot:true
},
需要在 main.js 手动指定哪些模块发生更新时,进行HMR
if (module.hot) {
module.hot.accpet("./utils/math.js", () => {
console.log("happen hot gengxin");
})
}
框架已经集成好了,不需要手动配置
## 3.4 host
devServer: {
hot: true,
// 端口位置
port: 8888,
// host设置主机地址,默认值是 localhost
host: '0.0.0.0',
open: ture,
// 自动把打包的文件进行gzip压缩
compress: true
},
打包适用于生产环境
创建 config 文件夹
使用 serve / build 是不同的两套配置
context 的作用:解析入口和加载器
"build": "webpack --config ./config/webpack.prod.config.js",
"serve": "webpack serve --config ./config/webpack.dev.config.js"
// 配置入口
// context:'',
// 相对于 context
entry: "./src/index.js",
很多配置是相似的
webpack.comm.config.js
npm i webpack-merge -D
webpack 跑在 node 当中,node 支持 commonjs
prod
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.comm.config");
module.exports = merge(commonConfig, {
mode: production,
output: {
clean: true,
},
});
const { merge } = require('webpack-merge')
const commonConfig = require('./webpack.comm.config')
module.exports = merge(commonConfig,{
mode: development,
devServer: {
hot: true,
// 端口位置
port: 8888,
// host设置主机地址,默认值是 localhost
host: "0.0.0.0",
open: ture,
// 自动把打包的文件进行gzip压缩
compress: true,
},
})
<script>
// 1.XHR网络请求
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(JSON.parse(xhr.responseText))
}
}
xhr.open('get', 'http://localhost:8000/users/list')
xhr.send()
// 2.fetch网络请求
fetch('http://localhost:8000/users/list').then(async res => {
const result = await res.json()
console.log(result)
})
</script>
安装:npm init -y
npm i webpack webpack-cli -D
mode
代码通常运行在浏览器上时,是通过 打包压缩 的:
但是,当代码报错需要调试时(debug),调试转换后的代码是很困难的
但是能保证代码不出错吗?不可能。
那么如何可以调试这种转换后不一致的代码呢?答案就是 source-map
devtool:'source-map',
## 6.5 source-map 值
mode:development
会生成 sourcemap,类似于 cheap-source-map,但是对源自 loader 的 sourcemap 处理会更好
需要用到开发环境中:mode:development
mode:production
// 被删除掉的
//# sourceMappingURL=bundle.js.map
webpack 底层就是使用 babel 转换代码
Babel是一个工具链,主要用于旧浏览器或者环境中将 ECMAScript 2015+ 代码转换为向后兼容版本的 JavaScript
包括:语法转换、源代码转换、Polyfill 实现目标环境缺少的功能等
npm install @babel/cli @babel/core
npm i @babel/plugin-transform-block-scoping -D
npm i @babel/plugin-transform-arrow-functions -D
npx babel src --out-dir dist
npm install @babel/preset-env -D
npx babel src --out-dir dist --presets=@babel/preset-env
babel 将一段代码(ES6、TypeScript、React)转成另外一段代码(ES5)
Babel 编译器的作用就是将源代码转换成浏览器可以直接识别的另外一段源代码
Babel 也拥有编译器的工作流程
使用:如果没有webpack 需要单独敲对应的命令:npx babel
npm i webpack webpack-cli -D
webpack 对应的是模块化的内容,babel 对应的是es6 转化为es5的内容–两者结合在一起
npm install babel-loader @babel/core -D
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader", //会自动去找对应的 babel 工具
options: {
// plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
presets: ["@babel/preset-env"],
},
},
},
],
},
npm install @babel/preset-env
兼容性:针对不同的浏览器支持的特性:比如 css 特性、js 语法之间的兼容性
市面上有大量的浏览器:
其实在很多的脚手架配置中,都能看到类似于这样的配置信息:
这里的百分之一,就是指市场占有率
> 1%
last 2 versions
not dead
代码要不要自动转换取决于要适配的浏览器
浏览器市场占有率caniuse
npx browserslist ">1%, last 2 version, not dead"
,真实开发不会使用 "browserslist":[]
Polyfill
为什么会用到 polyfill
使用
babel7.4.0 之前,可以使用 @babel/polyfill的包,但是该包现在已经不推荐使用了
babel7.4.0 之后,可以通过单独引入 core-js 和 regenerator-runtime 来完成 polyfill 的使用,安装:
npm install core-js regenerator-runtime
配置 babel.config.js
module.exports = {
// plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
presets: [
[
"@babel/preset-env",
{
// 指定使用版本
corejs: 3,
useBuiltIns:false
},
],
],
};
编写 react 代码时,react 使用的语法是 jsx,jsx 是可以直接使用 babel 来转换的
安装 react :npm i react react-dom
安装 preset :npm install @babel/preset-react -D
挂载到 index.html 上,需要打包 html 文件:npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require("HtmlWebpackPlugin ");
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
}),
],
module: {
rules: [
{
test: /\.jsx?$/, //x?:0或者1个
use: {
loader: "babel-loader", //会自动去找对应的 babel 工具
options: {
// plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
presets: [["@babel/preset-env", {}], ["@babel/preset-react"]],
},
},
},
],
},
可以通过 TypeScript 的 compiler 来转换成 JavaScript:npm install typescript -D
通过 tsc --init
为 TypeScript 的编译配置信息编写一个 tsconfig.json 文件
手动编译自己的ts代码:npx tsc
npm install ts-loader -D
{
test: /\.ts$/,
use:'ts-loader'
}
npm install @babel/preset-typescript -D
使用 Babel 来完成代码的转换,打包代码
使用 tsc 来进行类型的检查
在 scripts 中添加了两个脚本,用于类型检查