webpac5 + vite2 入门

Webpack笔记

从使用 webpack 的角度来说,搞清楚 webpack 的配置即可

安装

需要 node 14+ 和 npm(安装 node 时自动安装)。

全局安装

npm install webpack webpack-cli -g

局部安装(推荐)

npm init -y

-D 表示安装的开发依赖。加不加并不影响,但是推荐加,这样项目 package.json 会整洁些。

npm install webpack webpack-cli -D

基本使用

在新建项目的时候使用 webpack 打包会默认使用全局安装的 webpack,显然这可能导致兼容性的问题。一般来说,对于一个新项目,我们还是使用上面的局部安装方式自行安装一个 webpack。但是安装完再使用 webpack 进行打包还是会使用全局的 webpack,解决方法有两个:

  1. 使用 npx ./node_modules/webpack 手动执行当前目录下安装的 webpack
  2. package.json 中的 script 部分,加上一个自定义的指令,如 build,内容为 webpack,然后使用 npm run build 打包。(推荐
{
  "name": "01.basic_webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack" // 看这里
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

配置入口/输入文件路径

webpack 的默认入口文件为 ./src/index.js,输出文件为 ./dist,可以在执行 webpack 的时候,使用 --entry xxx 指定入口文件路径,--output-path 指定输入文件配置。

npx webpack --entry ./src/main.js --output-path ./build

我们可以在 package.json 中配置这样的指令,更好的解决方式是使用 webpack 的配置文件。

webpack 配置文件(webpack.config.js)

同 npm 的 package.json 一样,webpack 也有一个配置文件,一般在项目根目录,取名 webpack.config.js,内容如下:

// webpack.config.js
// 只能使用 CommonJS 的导出方法,因为 webpack 运行在 node 中

// 用 path.resolve 拼接路径
const path = require('path');

module.exports = {
  
    entry: './src/main.js',
    output: {
        // 这里只能填绝对路径
        path: path.resolve(__dirname, "build"),
        filename: 'bundle.js'
    }
}

webpack依赖图

假设有一个 element.js 用于给元素设置些样式,但是这个 js 文件没有被任何其他 js 文件引入,那么 webpack 打包的时候就不会把这个 js 打包。

解决方法:在 index.js 或者其他被 index.js import 的 js 文件中 import "element.js"

webpack 打包 css

注意,最新版 webpack 的 rules 外面要套一层 module 属性,具体见下方代码

注意,rules 的 loaders 数组的加载顺序是从后往前的,所以如果一个 loader 依赖另一个 loader,被依赖的 loader 要在依赖loader 的后面

默认情况下 webpack 只能打包 js,如果用类似 import xx.css 导入 css,会报错。这时需要配置 css-loader,示例配置如下:

// webpack.config.js
const path = require('path')

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'index.js'
    },
    module: {
    	rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'css-loader' // 需要事先安装 css-loader
                    }
                ]
            }
    	]
	}
}

可以看到我们在 webpack.config.js 中新增了一个 rules 字段,这个字段的值是一个对象数组,下面来详解 rules 的写法:

rules 的元素由 obj 构成,obj 的构成一般是

  • test 文件名匹配正则表达式
  • loader test 匹配成功后,使用的 loader
  • use test 匹配成功后,使用的 loaders
rules: [
    {
        // test 的值是一个正则表达式,符合正则表达式的文件会使用 use 或者 loader 的规则进行打包
        test: /\.ts$/,
        // loader 语法糖形式,适合只需要一个 loader 的情况
        // loader: 'typescript-loader'
        // 多个 loader
        use: [
            {
                loader: 'typescript-loader' 
            }
        ]
    },
    {
        test: /\.css$/,
        loader: 'css-loader'
    },
    {
        test: /\.less/,
        loader: 'less-loader'
    }
]

配合使用 postcss

postcss 是什么?

postcss 是一个 css 优化工具,可以实现对 css 的 polyfill 等功能。

安装 postcss 和 postcss-loader

npm install postcss postcss-cli postcss-loader -D

在 webpack 中配置 postcss

再次手写 webpack.config.js,权当复习 webpack 的配置写法。

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            // postcss 有个 postcssOptions
                            // 在 postcssOptions 中配置 plugins
                            postcssOptions: {
                                plugins: [
                                    // autoprefixer: 自动给样式添加浏览器前缀
                                    require('autoprefixer')
                                ]
                            }
                        }
                    }
                ]
            }
        ]
    }
}

或者用配置文件的写法

这里思路实际和 webpack 的配置文件类似:

在项目根目录创建一个 postcss.config.js

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
};

然后在 webpack.config.js 中,只用写 postcss-loader 而不用写配置。

配置文件的原理

很简单,加载 postcss 的时候,如果发现没有配置对象,那么就从 postcss.cofing.js 中读取导出对象,并作为 postcssOptions 传入。

配置补充

module.exports = {
    mode: 'production | deveploment',
    devtool: 'source-map'
}

  • mode 指定 webpack 的优化程度
  • devtool 设置为 source-map 方便开发中调试代码

练习

  1. 配置 less
  2. 配置 postcss 并安装 postcss-preset-env
  3. 使用单独的 postcss 配置文件 和 webpack 配置文件

webpack 资源

file-loader 打包图片

安装

npm install file-loader -D

使用

基本和打包 css 一样,看代码:

module.exports = {
    module: {
        rules: [
            // 打包图片
            test: /\.(jpe?g|png|svg|gif)/,
            loader: 'file-loader'
        ]
    }
}

在 css 中引入的时候,写法不变:

.bg {
    background: url("../img/1.jpg");
}

打包好的图片会被 hash 命名移动到输出文件夹里,webpack 会自动修改引入名。

在 js 中引入的时候,需要使用 require 或者 import 导入图片:

const div = document.createElement('div');
div.style.backgroundImage = require('../img/1.jpeg');

file-loader 的 placeholder 配置

rules: [
    {
        // 打包图片
        test: /\.(jpe?g|png|svg|gif)$/,
        use: {
            loader: 'file-loader',
            options: {
                name: 'img/[name]_[hash:6].[ext]'
            }
        }
    }
]

webpack5 asset 代替 file-loader/url-loader

module.exports = {
    module: {
        rules: [
            {
                test: /\.jpg$/,
                // 最常用的一种 type,可以自定义打包的大小阈值
                type: 'asset',
                generator: {
                  // 不同于 file-loader 的 placeholder,这里的 [ext] 自带 .
                  // 也就是无需再给文件名加 .
                  filename: 'img/[name]_[hash:6][ext]'  
                },
                parser: {
                    dataUrlCondition: {
                        // 文件没有超过 100KB,则打包成 base64
                        maxSize: 100 * 1024
                    }
                }
            }
        ]
    }
}

新增:

  • type
  • parser -> dataUrlCondition
  • generator 指定保存文件名

webpack 插件

基本使用

webpack 的插件放置在配置文件的 plugins 属性里,我们可以下载需要的插件,在配置文件中导入,然后添加到 plugins 数组中。

插件的命名一般是 xxx-webpack-plugin 其中 xxx 是插件实现的功能名。使用 require 导入插件,并没有统一的规范,有的插件需要结构得到配置类,有的不需要,具体可以查[官方文档](HtmlWebpackPlugin | webpack)

例子:

  • CleanWebpackPlugin 每次打包的时候自动删除上一次打包生成的文件
  • HtmlWebpackPlugin 提供一个 html 模板,生成的模板会在 dist 这类输出文件夹里。可以在模板中书写 EJS 表示,然后传入一些配置。
  • CopyWebpackPlugin 复制文件到指定 dist 输出文件夹
  • DefinePlugin webpack 官方集成的数据定义插件,可以传入 BASE_URL 等自定义数据。
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin  = require('Html-webpack-plugin');
const { CopyWebpackPlugin } = require('copy-webpack-plugin');
const DefinePlugin = require('webpack');

module.exports = {
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './public/index.html',
            title: 'Vue app'
        }),
        new DefinePlugin({
            // 这里传入的字符串会被当成变量名寻找,如果不想这样就需要传入一个字符串常量
            BASE_URL: "'./'"
        }),
        new CopyWebpackPlugin()
    ]
}

webpack 热替换HMR

首先讲下什么是 HMR 以及它和 live loading 的区别。

HMR 即模块热替换,当某个模块发生更新的时候,只有这个模块会被更新,而页面其它状态不会被更新。这也是 HMR 和 Live Loading 的区别——Live Loading是无脑刷新网页,不能保存网页状态,且更新代价比 HMR 大。

基本使用

  1. 安装 webpack-dev-server npm install webpack-dev-server -D

  2. 配置 package.json

    // ...
    scripts: {
        "serve": "webpack serve"
    }
    
    
  3. 启动 npm run serve

devServer 的简单配置

在 webpack.config.js 中,添加两个属性:

module.exports = {
    // ...
    target: "web" // 配置 webpack 的打包目标
    devServer: {
    	hot: true, // 启动 HMR;如果为 false 则是 live loading
    	contentBase: "./public", // webpack 没有打包的资源从这里找 如果有就用,没有才404,
        host: "127.0.0.1",
        port: 6767,
        open: true, // 是否自动打开浏览器
  	    compress: true // 是否开启 gzip 压缩
	}
}

本地开发解决跨域问题

同样的,在 devServer 属性中配置:

module.exports = {
    // ...
    target: "web" // 配置 webpack 的打包目标
    devServer: {
    	proxy: {
    		// 假设这里后端接口在 8899 端口,前端在 8888 端口
    		// 那么请求 /api 的时候,理想情况是请求 http://localhost:8899
    		// 但是这样配置还不能解决问题,因为 /api 会被重写成
    		// http://localhost:8899/api/xxx    因此需要配置重写设置
    
    		// "/api": "http://localhost:8899"
    
    		// 解决方案:/api 传入多个属性设置
    		"/api": {
    			// target 就是我们想访问的后端地址
    			target: "http://localhost:8899",
    			pathRewrite: {
    				// 以 /api 开头的请求会被重写为 ""
    				"^/api": ""
				},
    			// 默认情况下为 true,即不代理到 https
    			// 设为 false 即可解决上述问题
    			secure: false,
                // 
                changeOrigin: true
			}
		}
	}
}

Vite 笔记

开始 {#getting-started} | Vite中文网 (vitejs.cn)

了解完 webpack 后,我们来了解下 vite。vite 也是一个前端的构建工具,相比 webpack 它更加轻量,速度更快,且配置更少。vite 对 vue 提供首要支持,所以可以很轻松的创建 vue 项目。

安装

npm install vite

简单使用

创建一个前端项目,目录结构如下:

index.html
src
  main.js
  js
    app.js
   css
     style.css

其中,main.js中实现一些功能,同时因为需要打包 css 所以要使用 import ./css/style.css导入css。然后执行 npx vite 找到 node_modules/.bin/vite 运行 vite,看到提示后点击链接即可看到效果。导入 css 并不需要配置 loader。(main.js 需要用 module 模式引入)

导入 .less 文件时,需要安装 less;导入 .ts 文件时,无需执行任何配置;导入 .vue 文件时,需要安装 vite/plugin-vue@vue/sfc-compiler。然后创建 vite.config.js 写入如下内容:

// vite.config.js
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [vue()]
}

vite 的原理

vite1 使用 koa 作为后端语言,vite2使用 Connect 作为后端语言,这里用 vite2 举例。

当我们执行 npx vite 的时候,实际是启动了一个后端服务程序,浏览器访问资源的时候访问的就是导入的资源原文件,比如 style.less,这些请求被 Connect 接受,然后 304 跳转到编译成 style.css 的文件中。可以理解为 Connect 的主要作用就是转发浏览器无法解析的文件的请求。

vite 创建 vueapp

1. 安装 create-app

npm install @vitejs/create-app

1.1 执行

create-app

然后按提示操作即可。

1.2 create-app 的替代方案

npm init vite

功能和上面一样。

2.安装依赖

create-app 之后实际上只是生成了项目结构,使用npm install安装依赖,创建app。

3. 运行 & 打包

npm run dev

npm run build

上一篇:webstorm tailwind 不智能提示的解决方法


下一篇:rem适配方案