博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
构建工具是如何用 node 操作 html/js/css/md 文件的
阅读量:5826 次
发布时间:2019-06-18

本文共 4848 字,大约阅读时间需要 16 分钟。

构建工具是如何用 node 操作 html/js/css/md 文件的

从本质上来说,html/js/css/md ... 源代码文件都是文本文件,文本文件的内容都是字符串,对文本文件的操作其实就是对字符串的操作。

操作源代码的方式又主要分成两种:

  1. 当作字符串,进行增、删、改等操作
  2. 按照某种语法、规则,把字符串读取成一个对象,然后对这个对象进行操作,最后导出新的字符串

1. 操作 html 文件

html 的语法比较简单,并且一般操作 html 都是插入、替换、模板引擎渲染等在字符串上的操作,所以使用第一种方式的比较多。

比如:

  • 模板引擎
  • 模板引擎
  • 模板引擎

一般以第二种方式来操作 html 的都是将 html 文本解析成 dom 树对象,然后进行 dom 操作,最后再导出成新的代码文本。

比如:

cheerio 为例,操作 html 文本:

cheerio 能够加载一个 html 文本,实例化一个类 jQuery 对象,然后使用 jQueryapi 像操作 dom 一样操作这段文本,最后导出新的 html 文本。

const cheerio = require('cheerio');const $ = cheerio.load('

Hello world

'); // 加载一个 html 文本$('h2.title').text('Hello there!');$('h2').addClass('welcome');$.html(); // 导出新的 html 文本//=>

Hello there!

jsdom 为例,操作 html 文本:

jsdom 是用 js 将一个 html 文本解析为一个 dom 对象,并实现了一系列 web 标准,特别是 WHATWG 组织制定的 DOMHTML 标准。

const jsdom = require("jsdom");const { JSDOM } = jsdom;const dom = new JSDOM(`

Hello world

`);console.log(dom.window.document.querySelector("p").textContent); // "Hello world"

2. 操作 js 文件

因为 js 语法比较复杂,仅仅是如字符串一样进行增删改,只能做一些小的操作,意义不大。所以,一般操作 js 文件都是采用的第二种方式。

在第二种方式中,一般是工具将 js 文本解析成抽象语法树(AST,,),然后对这棵语法树以面向对象的方式做增删改等操作,最后再导出成新的代码文本。

生成抽象语法树的工具主要有:

  • : 比如 、、 等工具底层都是使用的 acorn 抽象语法树解析器
  • : 转码工具底层使用的抽象语法树解析器

acorn 为例,将 1 + 1 片段进行解析:

const acorn = require('acorn');const tree = acorn.parse('1 + 1');
// tree 的 json 化表示{  type: 'Program',  start: 0,  end: 5,  body: [{    type: 'ExpressionStatement',    start: 0,    end: 5,    expression: {      type: 'BinaryExpression',      start: 0,      end: 5,      left: { type: 'Literal', start: 0, end: 1, value: 1, raw: '1' },      operator: '+',      right: { type: 'Literal', start: 4, end: 5, value: 1, raw: '1' }     }  }],  sourceType: 'script' }

babel-parser 为例,将 1 + 1 片段进行解析:

const parser = require('@babel/parser');const tree = parser.parse('1 + 1');
// tree 的 json 化表示{  type: 'File',  start: 0,  end: 5,  loc: {    start: { line: 1, column: 0 },    end: { line: 1, column: 5 }   },  program: {    type: 'Program',    start: 0,    end: 5,    loc: {      start: { line: 1, column: 0 },      end: { line: 1, column: 5 }     },    sourceType: 'script',    interpreter: null,    body: [{      type: 'ExpressionStatement',      start: 0,      end: 5,      loc: {        start: { line: 1, column: 0 },        end: { line: 1, column: 5 }       },      expression: {        type: 'BinaryExpression',        start: 0,        end: 5,        loc: {          start: { line: 1, column: 0 },          end: { line: 1, column: 5 }         },        left: {          type: 'NumericLiteral',          start: 0,          end: 1,          loc: {            start: { line: 1, column: 0 },            end: { line: 1, column: 5 }           },          extra: { rawValue: 1, raw: '1' },          value: 1                },        operator: '+',        right: {          type: 'NumericLiteral',          start: 4,          end: 5,          loc: {            start: { line: 1, column: 0 },            end: { line: 1, column: 5 }           },          extra: { rawValue: 1, raw: '1' },          value: 1         }       }     }],    directives: []   },  comments: [] }

3. 操作 css 文件

css 的语法比 html 要复杂一些,一些简单的操作如插入、替换,可以用直接以字符串的方式操作,但如果是压缩、auto prefix、 等复杂的功能时,就需要用第二种方式操作 css 了。

在第二种方式中,一般也是将 css 文本解析成一棵抽象语法树,然后进行操作。

比如:

  • : 比如 、、 等的底层都是使用的 postcss 来解析
  • 、: 抽象语法树解析器
  • : 比如 的底层就是使用 csstree 来解析

postcss 为例,操作 css 文本:

const autoprefixer = require('autoprefixer');const postcss = require('postcss');const precss = require('precss');const css = `.hello {  display: flex;  color: red;  backgroundColor: #ffffff;}`;postcss([precss, autoprefixer({browsers: ['last 2 versions', '> 5%']})])  .process(css)  .then(result => {    console.log(result.css);  });

输出的文本:

.hello {  display: -webkit-box;  display: -ms-flexbox;  display: flex;  color: red;  backgroundColor: #ffffff;}

rework 为例,操作 css 文本:

const css = require('css');const ast = css.parse('body { font-size: 12px; }');console.log(css.stringify(ast));

输出的文本:

body {  font-size: 12px;}

4. 操作 markdown/md 文件

一般来说,操作 markdown 文本的目的有两个:

  1. 作为编辑器编辑 markdown 文本,或作为渲染器渲染 markdown 文本为 html 文本
  2. markdown 文本中读取信息、校验嵌入的源代码、优化格式等

所以,尽管 markdown 的语法也很简单,但一般并不会直接去使用字符串的方式去操作 markdown 文本,一般都是使用的第二种方式。

比如:

  • : 作为编辑器或渲染器的好手
  • : 构建抽象语法树进行操作的好手

markdown-it 为例,操作 markdown 文本:

const md = require('markdown-it')();const result = md.render('# markdown-it rulezz!');console.log(result);

输出的文本:

markdown-it rulezz!

remark 为例,操作 markdown 文本:

const remark = require('remark')const recommended = require('remark-preset-lint-recommended')const html = require('remark-html')const report = require('vfile-reporter')remark()  .use(recommended)  .use(html)  .process('## Hello world!', function(err, file) {    console.error(report(err || file))    console.log(String(file))  })

校验错误提示:

1:1  warning  Missing newline character at end of file  final-newline  remark-lint⚠ 1 warning

输出的文本:

Hello world!

后续

更多博客,查看

作者:

版权声明:自由转载-非商用-非衍生-保持署名()

你可能感兴趣的文章
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>
微信小程序蓝牙连接小票打印机
查看>>
环境错误2
查看>>
C++_了解虚函数的概念
查看>>
全新jmeter视频已经上架
查看>>
Windows 8下如何删除无线配置文件
查看>>
解决Windows 7中文件关联和打开方式
查看>>
oracle系列(五)高级DBA必知的Oracle的备份与恢复(全录收集)
查看>>
hp 服务器通过串口重定向功能的使用
查看>>
国外10大IT网站和博客网站
查看>>
android第十一期 - SmoothSwitchLibrary仿IOS切换Activity动画效果
查看>>
zabbix 批量web url监控
查看>>
MongoDB CookBook读书笔记之导入导出
查看>>
shell如何快速锁定所有账号
查看>>
HTML 5实现的手机摇一摇
查看>>
Linux 文件IO理解
查看>>
Ninject 2.x细说---2.绑定和作用域
查看>>
30个非常时尚的网页联系表单设计优秀示例
查看>>