zoukankan      html  css  js  c++  java
  • NodeJS 开发应用

    NodeJS 开发应用

    • 使用的 Node 版本: V8.11.4
    • 开发工具: VSCode 1.27.1
    • 系统: Deepin 15.7 Desktop x64

    项目结构

    项目结构

    • Project
      • index.html
      • index.js
      • package.json
      • yarn.lock
      • rollup.config.js
      • src
        • Main.js
        • ...(js files)
        • subdirs
          • ...(js files)
      • build
        • main.js

    yarn + rollup 构建应用程序

    最近在学习使用打包工具 yarn 构建应用程序。

    安装 yarn: npm i -g yarn。然后就可以在命令行中输入 yarn 命令:

    $ yarn -v
    1.9.4
    

    使用 yarn init 初始化新项目,这会在当前目录下创建一些文件,其中 package.json 文件是配置文件。

    在 package.json 中添加

    {
        ...
    
        "scripts": {
            "build": "rollup -c"
        }
    }
    

    然后在终端中输入 yarn build,实际将会执行 rollup -c 命令,为了能够使用 rollup,我们需要先添加依赖:yarn add rollup

    然后在当前目录下新建 rollup.config.js 文件,输入以下内容:

    export default {
    	input: 'src/Main.js',
    	output: [
    		{
    			format: 'umd',
    			name: 'Main',
    			file: 'build/main.js',
    			indent: '	'
    		},
    		{
    			format: 'es',
    			file: 'build/main.module.js',
    			indent: '	'
    		}
    	]
    };
    
    

    接下来运行 yarn build,将会在当前目录下(若不存在则创建)创建一个 build 目录,里面有两个生成的文件 main.jsmain.module.js

    在 Node 8.x 中监视文件变动情况

    首先要引用 fs 模块: const fs = require('fs');fs 模块提供了 watch 方法,用于监视某个文件夹中的文件变动情况,使用的 NodeJS 版本为 8.x,原本该版本的 Node 已经提供了递归监视子文件夹的选项,但是由于 recursive 选项仅在 Windows 系统和 macOS 系统下生效,因此此处只能监视某个特定的文件夹。

    以下是 nodejs 官网对 watch 函数的警告:

    Caveats

    The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.

    The recursive option is only supported on macOS and Windows.

    对于文件的监控实际上非常简单,fs.watch 方法会返回一个 fs.FSWatcher 对象,在该对象上注册 change 的回调函数即可。(也可以在调用 fs.watch 方法时将回调函数传递到第三个参数)

    const fs =  require('fs');
    const TO_WATCH = __dirname + '/src';
    
    function onChange(eventType, filename) {
        if( filename ) {
            console.log( filename );
        }
    };
    
    var watcher = fs.watch( TO_WATCH, { recursive: true } );
    watcher.on( 'change', onChange );
    

    接下来,使用 node 运行上述 JavaScript 代码,对 src 目录下的 Main.js 文件做一些改动,然后保存,在我的电脑的控制台上能够看到以下内容:

    Main.js
    Main.js
    

    可以看到,代码正确运行了,并且能够监视出是哪个文件变动。(尽管还有些小问题,Main.js 输出了两次,稍后就会解决这个问题)

    递归监视子文件夹

    前面提到过,在 Linux 系统中,fs.watch(filename[, options][, listener]) 方法的 recursive 选项不起作用,然而在 src 目录下常常需要根据代码功能划分不同的子模块(子文件夹),如果不对 Linux 系统作一些额外的处理的话,那么前面给出的 JavaScript 代码将无法监视 src 下的子目录文件变动。

    为了实现递归监视功能,需要用到 fs.readdir(path[, options], callback) 方法,在 node 10.x 中,该方法支持名为 withFileTypes: <boolean> 的选项,将该选项设为 true,在之后的回调函数中传递的 files 参数将不是一个字符串数组,而是一个 fs.Dirent[]。(fs.Dirent 对象自带有 isDirectory() 方法,自 10.10.0 版本后加入,使用起来是非常简单的。)

    然而很遗憾,在 node 8.x 中,该方法的选项仅支持 encoding: <string>,回调函数中传递的 files 参数只是一个字符串数组,所以为了判断出 src 目录下的文件是否为文件夹,还需要 fs.stat(path, callback) 方法:

    var watcher = [];
    watcher[0] = fs.watch( TO_WATCH, { recursive: true } );
    watcher[0].on( 'change', onChange );
    
    // on linux watch recursive option is invalid
    fs.readdir( TO_WATCH, { withFileTypes: true }, (err, files) => {
        if( err ) {
            throw err;
        }
    
        for(let i = 0; i < files.length; i++ ) {
            let file = files[i]
            // file is just the name of certain file, 
            // we have to prepend "src/" or the absolute path
            fs.stat( TO_WATCH + "/" + file, (err, stats) => {  
                if( err ) {
                    throw err;
                }
                
                if( stats && stats.isDirectory() ) {
    
                    let w = watcher.length;
                    watcher[w] = fs.watch( TO_WATCH + "/" + file );
                    watcher[w].on( 'change', onChange );
                }
            })
        }
    } );
    

    一切都准备就绪,对 src 的子目录下的文件做出修改并保存,可以在控制台上看到修改的文件名(不过仍然会打印两次文件名,打印的次数根据系统环境等不同而不同,因为 fs.watch API 不是 100% 稳定的)。

    为了防止修改一次文件而多次触发 onChange 回调函数,我们可以使用时间进行简单的过滤重复事件。

    var last = Date.now();
    function onChange(eventType, filename) {
        let nd = Date.now();
        if( nd - last > 100 && filename ) {
            console.log( filename );
        }
        last = nd;
    };
    

    这里判断 onChange 方法执行的间隔时间,如果小于 100ms 就只需要执行一次命令。现在在尝试改动 src 目录下的文件,就只会打印一次文件名了。

    文件变动时自动执行构建命令

    执行命令需要用到 child_porcess 模块中的 exec 方法,使用起来比较简单,执行之前在终端中输入的命令 yarn build:

    const exec = require('child_process').exec;
    
    exec("yarn build", (err, stdout, stderr) => {
        console.log( stdout );
    });
    

    这里只打印出标准输出,对于错误信息没有打印。

    总结

    以上不到 50 行的 JavaScript 代码就实现了递归监视目录及其子目录的功能,当目录中的文件变化时自动构建应用。由于 Node 10.x 中 watch 方法提供了递归监视的功能,可以对不同的 node 版本作不同的处理。但是这一功能并没有在本例的代码中实现。
    完整代码在 github 仓库 上。

    Reference

    https://yarnpkg.com/zh-Hans/docs/getting-started
    https://yarnpkg.com/zh-Hans/package/rollup
    https://nodejs.org/docs/latest-v8.x/api/fs.html

  • 相关阅读:
    input file 多张图片上传 获取地址 ——fileReader
    15个常用的javaScript正则表达式
    sublime-emmet
    AMD-requireJS
    jQuery-lazyload参数
    easyui 查询条件form 数据遍历
    导出excel设置金额格式
    html5页面添加时间戳
    创建枚举
    定义实体转json需要方法
  • 原文地址:https://www.cnblogs.com/brifuture/p/9612845.html
Copyright © 2011-2022 走看看