使用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实现获取当前url地址及url各种参数值
Jun 25 NodeJs
详解nodejs 文本操作模块-fs模块(五)
Dec 23 NodeJs
NodeJS基础API搭建服务器详细过程记录
Apr 01 NodeJs
详解nodejs中express搭建权限管理系统
Sep 15 NodeJs
nodejs实现大文件(在线视频)的读取
Oct 16 NodeJs
nodejs操作mongodb的填删改查模块的制作及引入实例
Jan 02 NodeJs
nodejs中Express与Koa2对比分析
Feb 06 NodeJs
nodejs取得当前执行路径的方法
May 13 NodeJs
nodeJs的安装与npm全局环境变量的配置详解
Jan 06 NodeJs
NodeJs内存占用过高的排查实战记录
May 10 NodeJs
详解NodeJS模块化
Jun 15 NodeJs
Node.js实现爬取网站图片的示例代码
Apr 04 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
php侧拉菜单 漂亮,可以向右或者向左展开,支持FF,IE
2009/10/15 PHP
ThinkPHP查询语句与关联查询用法实例
2014/11/01 PHP
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
Javascript执行效率全面总结
2013/11/04 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
2015/08/17 Javascript
Angular2学习教程之组件中的DOM操作详解
2017/05/28 Javascript
JavaScript实现各种排序的代码详解
2017/08/28 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
vue用递归组件写树形控件的实例代码
2018/07/19 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
vue父组件给子组件的组件传值provide inject的方法
2019/10/23 Javascript
[03:40]2014DOTA2国际邀请赛 B神专访:躲箭真的很难
2014/07/13 DOTA
Python面向对象编程中的类和对象学习教程
2015/03/30 Python
python制作花瓣网美女图片爬虫
2015/10/28 Python
在pandas中一次性删除dataframe的多个列方法
2018/04/10 Python
Python编写通讯录通过数据库存储实现模糊查询功能
2019/07/18 Python
python实现简单颜色识别程序
2020/02/19 Python
Python定时任务APScheduler原理及实例解析
2020/05/30 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
css3的@media属性实现页面响应式布局示例代码
2014/02/10 HTML / CSS
input元素的url类型和email类型简介
2012/07/11 HTML / CSS
美国新蛋IT数码商城:Newegg.com
2016/07/21 全球购物
Guess荷兰官网:美国服饰品牌
2020/01/22 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
瑞士男士时尚网上商店:Babista
2020/05/14 全球购物
SQL语言面试题
2013/08/27 面试题
党的群众路线教育实践活动党员个人剖析材料
2014/10/08 职场文书
2014年客房部工作总结
2014/11/22 职场文书
工人先进事迹材料
2014/12/26 职场文书
副总经理岗位职责
2015/02/02 职场文书
聚众斗殴罪辩护词
2015/05/21 职场文书
装修安全责任协议书
2016/03/22 职场文书
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS
win10拖拽文件时崩溃怎么解决?win10文件不能拖拽问题解决方法
2022/08/14 数码科技