本小节为上一小节的续篇,我们基于下面的导图继续实现 no-bundle 构建服务:
接下来我们需要完成如下的模块:
- CSS 编译插件
- 静态资源加载插件
- 模块依赖图开发,并在 transform 中间件中接入
- HMR 服务端代码开发
- HMR 客户端代码开发
# CSS 编译插件
首先,我们可以看看项目中 CSS 代码是如何被引入的:
// playground/src/main.tsx
import "./index.css";
@前端进阶之旅: 代码已经复制到剪贴板
为了让 CSS 能够在 no-bundle 服务中正常加载,我们需要将其包装成浏览器可以识别的模块格式,也就是 JS 模块,其中模块加载和转换的逻辑我们可以通过插件来实现。当然,首先我们需要在 transform 中间件中允许对 CSS 的请求进行处理,代码如下:
// src/node/server/middlewares/transform.ts
// 需要增加的导入语句
+ import { isCSSRequest } from '../../utils';
export function transformMiddleware(
serverContext: ServerContext
): NextHandleFunction {
return async (req, res, next) => {
if (req.method !== "GET" || !req.url) {
return next();
}
const url = req.url;
debug("transformMiddleware: %s", url);
// transform JS request
- if (isJSRequest(url)) {
+ if (isJSRequest(url) || isCSSRequest(url)) {
// 后续代码省略
}
next();
};
}
@前端进阶之旅: 代码已经复制到剪贴板
然后我们来补充对应的工具函数:
// src/node/utils.ts
export const isCSSRequest = (id: string): boolean =>
cleanUrl(id).endsWith(".css");
@前端进阶之旅: 代码已经复制到剪贴板
现在我们来开发 CSS 的编译插件,你可以新建src/node/plugins/css.ts文件,内容如下:
import { readFile } from "fs-extra";
import { Plugin } from "../plugin";
export function cssPlugin(): Plugin {
return {
name: "m-vite:css",
load(id) {
// 加载
if (id.endsWith(".css")) {
return readFile(id, "utf-8");
}
},
// 转换逻辑