使用NodeJS开发前端打包程序

简介: 使用NodeJS开发前端打包程序

使用NodeJS开发前端打包程序


每种语言都有自己的优势,互相结合各取所长使程序执行起来效率更高或者哪种实现方式较简单就用哪个,NodeJS是利用子进程来调用系统命令或者文件,文档见http://nodejs.org/api/child_process.html ,NodeJS子进程提供了与系统交互的重要接口,其主要API有: 标准输入、标准输出及标准错误输出的接口。

NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有:

标准输入、标准输出及标准错误输出的接口

child.stdin 获取标准输入

child.stdout 获取标准输出

child.stderr 获取标准错误输出

获取子进程的PID:child.pid

提供生成子进程的方法:child_process.spawn(cmd, args=[], [options])

提供直接执行系统命令的方法:child_process.exec(cmd, [options], callback)

提供调用脚本文件的方法:child_process.execFile(file, [args], [options], [callback])

提供杀死进程的方法:child.kill(signal='SIGTERM'

1、利用子进程调用系统命令(获取系统内存使用情况)

   新建nodejs文件,名为cmd_memory.js,代码如下:

var spawn = require('child_process').spawn;
free = spawn('free', ['-m']); 
// 捕获标准输出并将其打印到控制台 free.stdout.on('data', function (data) { console.log('standard output:\n' + data); 
}); 
// 捕获标准错误输出并将其打印到控制台 free.stderr.on('data', function (data) { console.log('standard error output:\n' + data); 
}); 
// 注册子进程关闭事件 free.on('exit', function (code, signal) { console.log('child process eixt ,exit:' + code); 
});

注意:运行该脚本和直接运行命令'free -m'的结果是一样的

2、利用NodeJS开发前端打包程序

       我们在做前端开发的时候经常会在部署上线的时候做程序的打包和合并,我们接下来就会对如何使用 node.js 开发前端打包程序做非常深入的讲解,希望能够帮到有需要的同学。

我们现在做前端开发更多的是多人共同协作开发,每个人负责不同的模块,便于开发和调试。这样就导致我们最后部署上线的时候需要把所有人开发的模块进行合并,生成单个或多个文件上线。如果手动合并的话肯定是费时又费力,而且非常容易出错,所以我们一般都是通过一些工具来实现自动合并的功能。

打包程序的原理非常简单,入口文件->寻找依赖关系->替换依赖关系->生成文件,其中中间的两个步骤是递归执行的。

我们先来看一下使用 node.js 如何完成一个简单的文件合并功能:

 

01// 打包文件内容
02 var contentList = [];
03 // 排重列表
04 var loadedFileList = {};
05
06 // 打包主程序
07 function combine(filePath){
08 // 这里获取入口文件的内容
09 var fileContent = fs.readFileSync(filePath);
10 // 遍历文件内容
11 fileContent.forEach(function(value){
12 // 这里的findImport是需要你来实现的方法,用正则来匹配依赖关系
13 var matchFile = findImport(value);
14 if(matchFile){
15 //如果匹配到依赖关系
16 If(!loadedFileList[matchFile]){
17 //如果依赖关系不在排重列表中,递归调用combine
18 combine(matchFile);
19 contentList.push(‘n’);
20 }
21 }else{
22 contentList.push(value);
23 }
24 });
25 }

       最后只要根据 contentList 里面的内容来生成文件就可以了,怎么样,是不是很简单呢?下面我们就要介绍另外一种方式,使用流来完成我们的打包程序。

在 node.js 中,流(Stream)是一个由不同对象实现的抽象接口。流可以是可读的、可写的、或者既可读又可写的。所有的流都是 EventEmitter 的实例。我们可以通过继承接口来构造我们自己所需要的流。在我们的打包程序里面需要两个流,一个负责按行输出文件内容,另外一个负责处理依赖关系。所有的文件内容都在这两个流里面循环流动,当所有的依赖关系都处理完毕之后就结束流动并生成对应的文件,这样就达到我们的目的了。

让我们先来看一下负责按行输出文件内容的流是怎么样的:

 

01 var Stream = require('stream').Stream,
02 util = require('util'),
03 path = require('path'),
04 fs = require('fs');
05
06 // 构造函数
07 function LineStream() {
08 this.writable = true;
09 this.readable = true;
10 this.buffer = '';
11 }
12
13 module.exports = LineStream;
14 // 继承流接口
15 util.inherits(LineStream, Stream);
16
17 // 重写write方法,所有pipe过来的数据都会调用此方法
18 LineStream.prototype.write = function(data, encoding) {
19 var that = this;
20 // 把buffer转换为string类型
21 if (Buffer.isBuffer(data)) {
22 data = data.toString(encoding || 'utf8');
23 }
24
25 var parts = data.split(/n/g);
26
27 // 如果有上一次的buffer存在就添加到最前面
28 if (this.buffer.length > 0) {
29 parts[0] = this.buffer + parts[0];
30 }
31
32 // 遍历并发送数据
33 for (var i = 0; i < parts.length - 1; i++) {
34 this.emit('data', parts[i]);
35 }
36 // 把最后一行数据保存到buffer,使传递过来的数据保持连续和完整。
37 this.buffer = parts[parts.length - 1];
38 };
39 // end方法,在流结束时调用
40 LineStream.prototype.end = function() {
41 // 如果还有buffer,发送出去
42 if(this.buffer.length > 0){
43 this.emit('data',this.buffer);
44 this.buffer = '';
45 }
46 this.emit('end');
47 };

       这样我们的 lineStream 就完成了,我们看到在 write 方法里面就做了一件事,分解传递过来的数据并按行发送出去,然后我们看下处理依赖关系的流 DepsStream。

 

01 var stream = require('stream').Stream;
02 var util = require('util');
03 var fs = require('fs');
04 var path = require('path');
05
06 module.exports = DepsStream;
07 util.inherits(DepsStream,stream);
08
09 function DepsStream(){
10 this.writable = true;
11 this.readable = true;
12 this.buffer = '';
13 this.depsList = [];
14 };
15
16 // 这里的write方法只发送数据,不对数据做任何的处理
17 DepsStream.prototype.write = function(data){
18 this.emit('data',data);
19 };
20
21 // 我们在这里重新pipe方法,使其能够处理依赖关系和生成最终文件
22 DepsStream.prototype.pipe = function(dest,opt){
23 var that = this;
24 function ondata(chunk){
25 var matches = findImport(chunk);
26 if(matches){
27 if(this.depsList.indexOf(matches) >= 0){
28 // 我们在这里把处理过后的数据pipe回lineStream
29 dest.write('n');
30 }else{
31 this.depsList.push(matches);
32 var code = getFileContent(matches);
33 // 我们在这里把处理过后的数据pipe回lineStream
34 dest.write('n' + code);
35 }
36 }else{
37 this.buffer += chunk + 'n';
38 }
39 }
40 function onend(){
41 // 生成最终文件
42 var code = this.buffer;
43 fs.writeFileSync(filePublishUrl,code);
44 console.log(filePublishUrl + ' combine done.');
45 }
46 // 监听end事件
47 that.on('end',onend);
48 // 监听data事件
49 that.on('data',ondata);
50 };
51
52 // end方法
53 DepsStream.prototype.end = function(){
54 this.emit('end');
55 };

      我们看到上面的程序里面我们在 pipe 方法里面监听了 end 事件和 data 事件,ondata 方法主要用来对数据进行处理,发现有依赖关系的话就获取对应依赖关系的文件并重新发回给 LineStream 进行处理。onend 方法用来生成最终的文件,我们来看一下最终的调用方法:

 

1 var fileStream = fs.createReadStream(filepath);
2 var lineStream = new LineStream();
3 var depsStream = new DepsStream();
4
5 fileStream.pipe(lineStream);
6 lineStream.pipe(depsStream);
7 depsStream.pipe(lineStream);


目录
相关文章
|
7天前
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
|
23天前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
43 1
|
14天前
|
Web App开发 JavaScript 前端开发
Node.js开发
Node.js开发
32 13
|
20天前
|
存储 JavaScript 前端开发
深入浅出Node.js后端开发
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将以Node.js为例,深入探讨其背后的哲学思想、核心特性以及在实际项目中的应用,旨在为读者揭示Node.js如何优雅地处理高并发请求,并通过实践案例加深理解。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和思考。
|
17天前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
本文将带你领略Node.js的魅力,从基础概念到实践应用,一步步深入理解并掌握Node.js在后端开发中的运用。我们将通过实例学习如何搭建一个基本的Web服务,探讨Node.js的事件驱动和非阻塞I/O模型,以及如何利用其强大的生态系统进行高效的后端开发。无论你是前端开发者还是后端新手,这篇文章都会为你打开一扇通往全栈开发的大门。
|
21天前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
在这篇文章中,我们将一起探索Node.js的奇妙世界。无论你是刚接触后端开发的新手,还是希望深化理解的老手,这篇文章都适合你。我们将从基础概念开始,逐步深入到实际应用,最后通过一个代码示例来巩固所学知识。让我们一起开启这段旅程吧!
|
17天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带领读者从零基础开始,一步步深入到Node.js后端开发的精髓。我们将通过通俗易懂的语言和实际代码示例,探索Node.js的强大功能及其在现代Web开发中的应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的见解和技巧,让你的后端开发技能更上一层楼。
|
20天前
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
21天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带你走进Node.js的世界,从基础到进阶,逐步解析Node.js在后端开发中的应用。我们将通过实例来理解Node.js的异步特性、事件驱动模型以及如何利用它处理高并发请求。此外,文章还会介绍如何搭建一个基本的Node.js服务器,并探讨如何利用现代前端框架与Node.js进行交互,实现全栈式开发。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
16 4
|
28天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
【10月更文挑战第40天】在这篇文章中,我们将一起探索Node.js的奥秘,从基础概念到实际应用,逐步揭示如何利用Node.js构建高效、可扩展的后端服务。通过实际案例分析,我们将了解Node.js在现代Web开发中的应用,以及如何克服常见的开发挑战。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的见解和实用的技巧,帮助你在Node.js的道路上更进一步。
29 4