使用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中读取中文文件编码问题、发送邮件和定时任务实例
Jan 01 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 NodeJs
nodejs实现bigpipe异步加载页面方案
Jan 26 NodeJs
Nodejs 获取时间加手机标识的32位标识实现代码
Mar 07 NodeJs
实例分析nodejs模块xml2js解析xml过程中遇到的坑
Mar 18 NodeJs
NodeJS测试框架mocha入门教程
Mar 28 NodeJs
详解nodejs操作mongodb数据库封装DB类
Apr 10 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
Sep 06 NodeJs
Nodejs封装类似express框架的路由实例详解
Jan 05 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 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
动态新闻发布的实现及其技巧
2006/10/09 PHP
PHP实用函数分享之去除多余的0
2015/02/06 PHP
PHP的cURL库简介及使用示例
2015/02/06 PHP
Django中的cookie与session操作实例代码
2017/08/17 PHP
PHP函数按引用传递参数及函数可选参数用法示例
2018/06/04 PHP
js 鼠标拖动对象 可让任何div实现拖动效果
2009/11/09 Javascript
解析JavaScript中delete操作符不能删除的对象
2013/12/03 Javascript
jQuery选择器全面总结
2014/01/06 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
Bootstrap对话框使用实例讲解
2016/09/24 Javascript
jQuery实现右键菜单、遮罩等效果代码
2016/09/27 Javascript
JSONP基础知识详解
2017/03/19 Javascript
vue.js项目打包上线的图文教程
2017/11/16 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
angularjs通过过滤器返回超链接的方法
2018/10/26 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
浅谈JS的原型和继承
2019/05/08 Javascript
EasyUI 数据表格datagrid列自适应内容宽度的实现
2019/07/18 Javascript
swiper实现异形轮播效果
2019/11/28 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
python3使用matplotlib绘制散点图
2019/03/19 Python
如何运行.ipynb文件的图文讲解
2019/06/27 Python
Python csv模块使用方法代码实例
2019/08/29 Python
python + selenium 刷B站播放量的实例代码
2020/06/12 Python
10种CSS3实现的loading动画,挑一个走吧?
2020/11/16 HTML / CSS
车间工艺员岗位职责
2013/12/09 职场文书
幼儿园小班评语大全
2014/04/17 职场文书
盲山观后感
2015/06/11 职场文书
田径运动会广播稿
2015/08/19 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
pytorch中[..., 0]的用法说明
2021/05/20 Python
MySQL数据库超时设置配置的方法实例
2021/10/15 MySQL
AJAX实现指定部分页面刷新效果
2021/10/16 Javascript