停止使用 ejs 和 pug 并使用 tsx 编写 html?
介绍
这是一个html模板选择的故事。
对于不叫Modern Front的项目,我们还是使用ejs、pug等html模板引擎库来编写和交付html。
这一次,我们说的是采用 tsx 作为这样的模板引擎。
结论
将renderToStaticMarkup中的tsx文件(react-dom的函数)转换成字符串,输出为html文件。这使得使用 tsx 表示法生成 html可以做。
下面是一个使用 webpack 自动编译的示例。
ejs 和 pug 的局限性
ejs和pug可以用html来描述JavaScript,可以用if, for, switch, try/catch等js语法,用let, const进行变量声明,用include进行部分文件的提取和读取,可以高效处理html。
但是,随着项目(以下简称 PJ)的发展,您可能会感到各种限制。
- 无法进行 lint 检查(如果你寻找它,可能有IDE扩展)
- 未键入 include 的参数
- 在编译之前我不知道错误&失败时难以识别错误位置
- 限制你的感觉
为了解决上面的问题,我想介绍一下 React 的语法 tsx 作为 html 模板引擎。
tsx 的优势
tsx 首先是什么?
jsx 是 JavaScript 语法的扩展,是用 TypeScript 编写的。
这里是对jsx的详细解释。
与 ejs 能够在 html 中编写 JavaScript 的形象相比,jsx 就像能够在 JavaScript 中编写 HTML。
使用 tsx 可以解决 ejs 和 pug 的局限性
作为前提,上面出现的所有ejs和pug函数if, for, const, include都可以用tsx实现。
最重要的是,您可以解决使用 ejs 和 pug 时遇到的问题。
- 无法检查 lint 的问题
- 已解决,因为 eslint 按原样运行。
-
include 参数未输入
- 由于参数作为 props 传递给部分文件,这是 tsx (/jsx) 的函数,因此可以使用静态类型。
- 难以理解错误位置
- Eslint 运行,所以在编码时解决
另一个优点是学习成本很低,因为您没有创建 React 应用程序。
简单地记住 jsx 语法(if 是单行,for 是 map 等)与学习 ejs 和 pug 语法没有太大区别。
如何将 tsx 转换为 html
我们来看看具体的实现。
首先,使用ReactDOMServer对象的renderToStaticMarkup方法作为将tsx转换为html的方法。
tsx 被 React 转换为 JavaScript 一次,但是可以通过上面的函数在 Node 服务器上转换为静态的 html 字符串。
我将介绍两种方法,一种使用 webpack,一种不使用。
1.没有webpack的方法
首先,我们将了解如何使用ts-node 简单地编译 tsx,而不使用 webpack 并输出 html。
你需要的包
yarn add -D @types/node @types/react @types/react-dom react react-dom ts-node typescript
适当准备tsconfig.json(需要设置"jsx": "react-jsx"),准备以下文件。
页面.tsximport ReactDOMServer from "react-dom/server"; const App = () => { return ( <div> <h1>App Page.</h1> <p>description.</p> </div> ); }; const pageString = ReactDOMServer.renderToString(<App />); const page = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Title</title> </head> <body> ${pageString} </body> </html> `; console.log(page); export default page;
执行以下命令会将字符串化的 html 输出到控制台。
我看到你可以从 tsx 生成 html 字符串。
$ ts-node page.tsx
您所要做的就是根据这个字符串生成一个 html 文件。
我认为使用 Node.js 函数的方法有很多,但以下是一个示例。
import fs from "fs"; import path from "path"; import page from "./page"; const writeFile = async (file: string, data: string): Promise<void> => { await fs.promises.mkdir(path.dirname(file), { recursive: true }); fs.promises.writeFile(file, data); }; const filename = path.basename(__filename, ".ts"); writeFile(path.resolve(__dirname, `build/${filename}.html`), page);
build/index.html 在我运行时被喷出。
$ ts-node index.ts
我能够使用 tsx 作为模板引擎!
2.如何使用webpack
嗯,我发现用上面的方法可以从tsx生成html。但是,当必要页面的数量增加时,它似乎有点麻烦。
那么让我们使用 webpack 搭建一个自动编译环境。
(那些说不需要 webpack 的人之后就不需要了。)
首先安装所需的软件包。
$ yarn add -D @types/react @types/react-dom esbuild-loader globule html-webpack-plugin html-webpack-skip-assets-plugin prettier react react-dom@17.0.2 typescript webpack webpack-cli webpack-dev-server
※笔记※
react-dom 库的最新版本是 2005 年 10 月 22 日的 ver.18,但由于某种原因,当它是 ver.18 时,它无法编译并出现错误 Error: TextEncoder is not defined。 (如果你知道为什么,请...)
所以我安装了ver.17。
使用export html 字符串(如page.tsx 和HtmlWebpackPlugin)对tsx 文件进行grep,以自动将其编译为html 文件。
我将编写一个脚本,以便即使屏幕数量像 MPA 一样增加,也可以完成 grep。我将globule 库用于grep。
const path = require('path'); const globule = require('globule'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const {HtmlWebpackSkipAssetsPlugin} = require('html-webpack-skip-assets-plugin'); const assignPlugins = (env) => { const globuleFiles = ['**/*.tsx', '!**/_*.tsx', '!**/_partials/**/*.tsx']; /** 指定されたディレクトリからgrepしたtsxファイル */ const templateFiles = globule.find([...globuleFiles], {cwd: `${__dirname}/src/pages`}); /** entryファイルを格納したオブジェクトを作成 */ const entriesList = templateFiles.reduce((temp, current) => { temp[`${current.replace(new RegExp(`.tsx`, 'i'), `.html`)}`] = `${__dirname}/src/pages/${current}`; return temp; }, {}); const assignObject = { plugins: [] }; for (const [htmlFileName, tempFileName] of Object.entries(entriesList)) { assignObject.plugins.push(new HtmlWebpackPlugin({ filename: htmlFileName, template: tempFileName })); env.WEBPACK_BUILD && assignObject.plugins.push(new HtmlWebpackSkipAssetsPlugin({ excludeAssets: [/entry.js/] })); } return assignObject; }; module.exports = (env) => ( Object.assign({ entry: './src/entry', output: { path: path.join(__dirname, 'dist'), filename: 'entry.js' }, devtool: false, watchOptions: { ignored: /node_modules/ }, resolve: { extensions: ['.js', '.ts', '.tsx'], }, module: { rules: [ { test: /.tsx$/, use: [ { loader: 'esbuild-loader', options: { loader: 'tsx', } } ] }, ], }, devServer: { ... watchFiles: [ 'src/**/*.tsx' ], }, }, assignPlugins(env)); );
需要准备入口文件,所以直接在src目录下准备entry.js。
积分
- 入口文件entry.js 会在构建时自动从html 中的script 元素中读取,但它是不必要的文件,因此不会输出HtmlWebpackSkipAssetsPlugin。
但是,在开发过程中,除非读取这个入口文件,否则它不会被编译,所以这个插件只有在env.WEBPACK_BUILD是true时才会被读取(构建时)。 - 为 devServer.watchFiles 选项指定 'src/**/*.tsx' 以根据 tsx 文件的变化使 webpack-dev-server 热重载。
▼ 这里是刚刚吐出html的最小环境
奖金
由于自己搭建了webpack环境,所以尝试创建一个可以同时编译sass和typescript的环境。
yarn start 将启动本地服务器,yarn build 将在 dist 目录下构建它。
好像每个项目都需要设置图片压缩,所以一次都没放。
[额外奖励] 从 html 到 tsx 的转换
在将现有的 html 文件转换为 tsx 以进行增强等并对其进行开发时,有必要的过程,例如重写和转义反引号,我觉得手动操作很麻烦/辛苦,所以我用脚本将它自动化。我是被允许。
在pages目录下新建一个转换前的html文件,执行以下命令生成同名的tsx文件。 (html文件被删除)
$ node convertHtmlToTsx.js
由于有新文件差异的文件是用 git 一次性转换的,所以可以同时转换多个文件。
源代码是这里是。
概括
我尝试使用 tsx 作为 html 模板引擎构建环境。
最近SPA、s-s-r、SSG已经成为主流,webpack本身也在消亡,但我觉得还是有项目交付静态html的。
如果我能为改善某人的开发体验做出贡献,我会很高兴。
参考文章
本文用作创建存储库的参考。谢谢你。
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308628452.html
总结
以上是如意编程网为你收集整理的停止使用 ejs 和 pug 并使用 tsx 编写 html?的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: VsCode运行html界面的实战步骤
- 下一篇: HTML div右边怎么加边框