使用nodejs分离html文件里的js和css详解


Posted in NodeJs onApril 12, 2019

摘要: 本文要实现的内容,使用nodejs 对文件的增删改查,演示的例子-》分离出一个html 文件里面的script 和style 里面的内容,然后单独生成js文件和css 文件。中间处理异步的api-》async/await , Promise

项目托管:extract-js-css , 欢迎star

直接上代码:

// extract-js-css

// import fs from 'fs'

var fs = require('fs')

// import csscomb from 'csscomb'

// var csscomb = require('csscomb')

// var comb = new csscomb('zen');

// console.log(comb)

 

// 删除文件

const deleteFile = (path)=>{

  return new Promise(resolve => {

    fs.unlink(path, (err) => {

      if (err) {

        console.log(err)

        return

      };

      console.log(`已成功删除 ${path}文件`);

      resolve()

    });

  })

}

 

// 删除文件夹

const deleteDir = async (path)=>{

  let _files = await new Promise (resolve => {

    fs.readdir(path, (err,files) => {

      if (err) {

        console.log(err)

      };

      console.log(`已成功读取 ${path} 文件夹`);

      resolve(files)

    })

  })

 

  if(_files && _files.length) {

    for(let i =0;i<_files.length;i++) {

      // console.log(_files[i],'innnnnn')

      await deleteFile('./test/'+ _files[i])

    }

  }

  // console.log('delete hou')

 

  await new Promise(resolve => {

    fs.rmdir(path, (err) => {

      if (err) {

        console.log(err)

      };

      console.log(`已成功删除空 ${path}文件夹`);

      resolve()

    })

  });

}

const emptyDir = (path) => {

  return new Promise(resolve => {

    fs.rmdir(path, (err) => {

      if (err) {

        console.log(err)

      };

      console.log(`已成功删除空 ${path}文件夹`);

      resolve()

    })

  })

}

// 新建文件夹

/**

 * 

 */

const mkdirTest = ()=>{

  return new Promise(resolve => {

    fs.mkdir('./test', { recursive: true }, (err, data)=>{

      if (err) {

        console.log(err)

      };

      console.log('新建文件夹成功')

      resolve()

    })

  })

}

 

// 读取html 内容

/**

 * 

 */

const readHtml = ()=>{

  return new Promise(resolve => {

    fs.readFile('./test.html', 'utf-8', (err, data)=>{

      if(err) {

        throw Error(err)

      }

      console.log('test.html 读取成功!--NO1')

      resolve(data)

    })

  })

}

 

// 写入css 和js

/**

 * 向文件中追加内容

 * @param {是文件名字} path 

 * @param {写入文件的内容} data 

 * @param {文件类型} type 

 * @author erlinger

 * @time 

 */

const appendFile = (path, data, type) => {

  return new Promise(resolve => {

    fs.appendFile(path, data, (err) => {

      if (err) {

        console.log(err)

      };

      console.log(`${type}数据已追加到文件`);

      resolve()

    });

  })

}

// 写一个html

const writeHtml = (path, data) => {

  return new Promise(resolve => {

    fs.writeFile(path, data, (err) =>{

      if(err) {

        console.log('err', err)

        return

      }

      console.log(`${path} 写入成功,功能结束!`);

      resolve() // 必须resolve 。不然 promise 就到此为止,调用该方法后面的代码将不执行

    })

  })

}

 

// 插件 方法入口

(async ()=>{

  console.log('==========================game-start=============================');

  await deleteDir('./test');

  console.log('我应该是等---删除文件夹后---才出现')

 

  await mkdirTest();

  console.log('我应该是在---文件夹新建成功---后出现!');

 

  let cssReg = /<style>[\s|\S]*?<\/style>/ig;

  let jsReg = /<script>[\s|\S]*?<\/script>/ig;

  let allStyleReg = /<\/style>[\s|\S]*?<style>/ig;

  let allScriptReg = /<\/script>[\s|\S]*?<script>/ig;

  let cssLink = '<link rel="stylesheet" href="./test.css" rel="external nofollow" >';

  let jsrc = '<script src="./test.js"></script>';

  let styleCollection, scriptColletion;

  let cssContent = '', jsContent = '', htmlContentStr = '';

 

  let originContent = await readHtml();

  styleCollection = originContent.match(cssReg);

  scriptColletion = originContent.match(jsReg);

   

  // 处理 css

  for (let i =0;i<styleCollection.length;i++) {

    cssContent += JSON.stringify(styleCollection[i]);

  }

 

  cssContent = cssContent.replace(/<style>/g,'').replace(/<\/style>/g, '').replace(/("")/g,'')

   

  for (let i =0;i<scriptColletion.length;i++) {

    jsContent += JSON.stringify(scriptColletion[i]);

  }

   

  jsContent = jsContent.replace(/<script>/g,'').replace(/<\/script>/g, '')

  .replace(/<\/script>"*<script>/g, '').replace(/("")/g,'')

   

  await appendFile('./test/test.css', JSON.parse(cssContent), 'css');

  console.log('我应该是在---css写入成功---后出现!');

 

  await appendFile('./test/test.js', JSON.parse(jsContent), 'js');

  console.log('我应该是在---js写入成功---后出现!');

 

  htmlContentStr = originContent

  .replace(allStyleReg, '')

  .replace(cssReg, cssLink)

  .replace(allScriptReg, '')

  .replace(jsReg, jsrc);

  console.log('copyTest.html 文本已经格式化,准备写入');

  await writeHtml('./test/copyTest.html', htmlContentStr);

 

  console.log('==========================game-over=============================');

})()

代码确实没什么好解释的,慢慢看就明白了。运行:

node extract-js-css

如果你要使用 es6 module,用 import 导入方法,需要单独装一个babel,使用这个包去编译成es5,在运行,具体使用可以down项目运行一下。

针对此项目,需要提醒说明以下:

对文件的处理都是异步操作,如果是单一的一个异步操作方法(比如:appendFile 方法),它就是往文件里面异步添加内容,直接封装成一个promise,然后 return 出来就好。

如果一个操作里面包含多个异步处理逻辑的就需要在这个方法里面,用async 声明方法,用await 等待异步操作,最后return 出去一个promise

在执行主流程中,我们用async声明的方法进行调用(我这里是匿名函数直接调用) ,用await 进行等待异步操作,这样我们的主流程就是一个同步的执行的流程,看起来很爽朗。

文中的异步操作文件的api 方法是异步的,nodejs 开发文档提供了同步操作文档,大家可以直接使用同步的api。我这里主要是联系在异步操作的过程中,使用async/ await promise 方法,更好的掌握它。

文中的一个demo 提供了处理多个异步、一个异步操作里面包含多个异步操作,包括在循环里执行异步操作 的一个方案,里面具体针对HTML 文件的字符串处理,比较搓搓,在用正则匹配和字符串格式化和解析字符串的情况比较单一。在读取完文件内容后,需要 JSON.stringify,后来在填入文件中的时候要 JSON.parse , 目前没找到合适的方法,如果有大佬有合适的方法,欢迎告知与我,大家一起交流。

下面是 执行一个主 async方法的一个过程

使用nodejs分离html文件里的js和css详解

NodeJs 相关文章推荐
基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案
Sep 26 NodeJs
Nodejs express框架一个工程中同时使用ejs模版和jade模版
Dec 28 NodeJs
Nodejs--post的公式详解
Apr 29 NodeJs
nodejs6下使用koa2框架实例
May 18 NodeJs
ajax +NodeJS 实现图片上传实例
Jun 06 NodeJs
nodejs中解决异步嵌套循环和循环嵌套异步的问题
Jul 12 NodeJs
NodeJS简单实现WebSocket功能示例
Feb 10 NodeJs
NodeJS父进程与子进程资源共享原理与实现方法
Mar 16 NodeJs
PHPStorm中如何对nodejs项目进行单元测试详解
Feb 28 NodeJs
nodejs使用async模块同步执行的方法
Mar 02 NodeJs
nodejs简单抓包工具使用详解
Aug 23 NodeJs
nodejs开发一个最简单的web服务器实例讲解
Jan 02 NodeJs
nodejs分离html文件里面的js和css的方法
Apr 09 #NodeJs
NodeJs操作MongoDB教程之分页功能以及常见问题
Apr 09 #NodeJs
Nodejs核心模块之net和http的使用详解
Apr 02 #NodeJs
Nodejs中的require函数的具体使用方法
Apr 02 #NodeJs
NodeJs之word文件生成与解析的实现代码
Apr 01 #NodeJs
详解nodejs http请求相关总结
Mar 31 #NodeJs
详解Nodejs get获取远程服务器接口数据
Mar 26 #NodeJs
You might like
php5 图片验证码实现代码
2009/12/11 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
PHP浮点比较大小的方法
2016/02/14 PHP
PHP 以POST方式提交XML、获取XML,解析XML详解及实例
2016/10/26 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
php微信公众号开发之翻页查询
2018/10/20 PHP
yii2实现Ueditor百度编辑器的示例代码
2018/11/02 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
2019/12/12 PHP
JQery 渐变图片导航效果代码 漂亮
2010/01/01 Javascript
Javascript实现关联数据(Linked Data)查询及注意细节
2013/02/22 Javascript
JavaScript不使用prototype和new实现继承机制
2014/12/29 Javascript
javascript实现验证身份证号的有效性并提示
2015/04/30 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
jquery实现的蓝色二级导航条效果代码
2015/08/24 Javascript
vue-cli如何引入bootstrap工具的方法
2017/10/19 Javascript
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
2018/08/24 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
基于vue-cli3创建libs库的实现方法
2019/12/04 Javascript
[02:44]重置世界,颠覆未来——DOTA2 7.23版本震撼上线
2019/12/01 DOTA
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
举例详解Python中循环语句的嵌套使用
2015/05/14 Python
python+matplotlib绘制3D条形图实例代码
2018/01/17 Python
如何用python整理附件
2018/05/13 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
Python实现定时自动关闭的tkinter窗口方法
2019/02/16 Python
python查看数据类型的方法
2019/10/12 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
2020/09/21 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
CSS3实现时间轴效果
2016/07/11 HTML / CSS
阿迪达斯越南官网:adidas越南
2020/07/19 全球购物
在校大学生个人的自我评价
2014/02/13 职场文书
上海世博会志愿者口号
2014/06/17 职场文书
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL