buildtools如何用node操作html/js/css/md文件本质上,html/js/css/md...源码文件都是文本文件,文本文件的内容都是字符串。对文本文件的操作其实就是对字符串的操作。对源码的操作主要有两种方式:把它当做一个字符串,增删改查等,把字符串按照一定的语法和规则读入一个对象,然后对这个对象进行操作,最后导出一个新的1、操作html文件html的语法比较简单,而html的一般操作都是对字符串的操作,如插入、替换、模板引擎渲染等,所以经常使用第一种方法。例如:html-loaderhtml-webpack-pluginhtml-minifierhandlebars模板引擎pug模板引擎ejs模板引擎操作html一般采用第二种方式,就是将html文本解析成dom树对象,然后进行dom操作,最后导出进入一个新的代码文本。例如:cheeriojsdomparse5以cheerio为例来操作html文本:cheerio可以加载一个html文本,实例化一个jQuery-like对象,然后使用jQuery的api像dom一样操作这个文本,最后导出新的html文本。constcheerio=require('cheerio');const$=cheerio.load('Helloworld');//加载html文本$('h2.title').text('你好!');$('h2').addClass('欢迎');$.html();//导出新的html文本//=>Hellothere!以jsdom为例操作html文本:jsdom使用js将一段html文本解析为dom对象,并实现了一系列的Web标准,特别是WHATWG组织制定的DOM和HTML标准。constjsdom=require("jsdom");const{JSDOM}=jsdom;constdom=newJSDOM(`Helloworld
`);console.log(dom.window.document.querySelector("p").textContent);//"Helloworld"2.操作js文件因为js语法比较复杂,就像对字符串进行增删改查,只能做一些小操作,意义不大。所以一般使用第二种方式来操作js文件。第二种方法,工具一般是将js文本解析成抽象语法树(AST,AbstractSyntaxTree,抽象语法树),然后以面向对象的方式对语法树进行增删改查,最后导出进入新的代码文本。生成抽象语法树的工具主要有:Acorn:acorn底层使用的抽象语法树解析器如webpack、rollup、UglifyJS等工具babel-parser:babel底层使用的抽象语法树解析器转码工具以acorn为例,解析1+1段:constacorn=require('acorn');consttree=acorn.parse('1+1');//树的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片段:constparser=require('@babel/parser');consttree=parser.parse('1+1');//树的json表示{type:'File',start:0,end:5,loc:{start:{line:1,column:0},结束:{行:1,列:5}},程序:{类型:'程序',开始:0,结束:5,loc:{开始:{行:1,列:0},结束:{行:1,丙column:5}},sourceType:'script',interpreter:null,body:[{type:'ExpressionStatement',start:0,end:5,loc:{start:{line:1,column:0},end:{行:1,列:5}},表达式:{类型:'BinaryExpression',开始:0,结束:5,loc:{开始:{行:1,列:0},结束:{行: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:{开始:{line:1,column:0},end:{line:1,column:5}},extra:{rawValue:1,raw:'1'},值:1}}}],指令:[]},注释:[]}3。操作css文件css的语法比html复杂,一些简单的操作如插入替换可以直接以字符串操作的形式完成,但是对于复杂的功能如压缩,autoprefix,css-modules,等等,需要使用第二种方法来操作css。第二种方法,一般是将css文本解析成抽象语法树,然后进行操作。例如:postcss:css-loader、autoprefixer、cssnano等底层都使用postcss解析返工,返工:constautoprefixer=require('autoprefixer');constpostcss=require('postcss');constprecss=require('precss');constcss=`.hello{显示:flex;红色;backgroundColor:#ffffff;}`;postcss([precss,autoprefixer({browsers:['last2versions','>5%']})]).process(css).then(result=>{console.log(结果.css);});输出文本:.hello{display:-webkit-box;显示:-ms-flexbox;显示:弹性;红色;backgroundColor:#ffffff;}以rework为例,操作css文本:constcss=require('css');constast=css.parse('body{font-size:12px;}');console.log(css.stringify(ast));输出文本:body{font-size:12px;}4.操作markdown/md文件一般来说,操作markdown文本有两个目的:作为编辑器编辑markdown文本,或者作为渲染器将markdown文本渲染为html文本,从markdown文本中读取信息,校对因此,虽然语法markdown也很简单,一般不会直接使用字符串来操作markdown文本,一般使用第二种使用方式,例如:markdown-it:作为编辑器或渲染器的好播放器remark:构建抽象语法树进行操作的好播放器=require('markdown-it')();constresult=md.render('#markdown-itrulezz!');console.log(result);输出文本:markdown-itrulezz!
以remark为例,操作markdown文本:constremark=require('remark')constrecommended=require('remark-preset-lint-recommended')consthtml=require('remark-html')constreport=require('vfile-reporter')remark().use(recommended).use(html).process('##Helloworld!',function(err,file){console.error(report(err||file))console.log(String(file))})验证错误信息:1:1warningMissingnewlinecharacteratendoffilefinal-newlineremark-lint?1warningoutputtext:Helloworld!
跟进更多博客请查看https://github.com/senntyou/blogs作者:沉育智(@senntyou)版权声明:免费转载-非商业-非衍生-保留署名(CreativeCommons3.0许可)