你不知道的opn模块

前言

opn模块通常是作为跨平台的打开文件或者网站的模块,在web应用中最常见的使用是比如项目开发或者启动的时候打开浏览器进行访问。

优点

  • 长期维护
  • 支持应用参数
  • 因为它使用spawn而不是更安全exec
  • 修复了大部分未node-open解决的问题
  • 包含Linux 的最新xdg-open脚本

模块地址

https://npm.taobao.org/package/opn

基本使用

安装

$ npm install opn

使用

const opn = require('opn');

// Opens the image in the default image viewer
opn('unicorn.png').then(() => {
    // image viewer closed
});

// Opens the url in the default browser
opn('http://sindresorhus.com');

// Specify the app to open in
opn('http://sindresorhus.com', {app: 'firefox'});

// Specify app arguments
opn('http://sindresorhus.com', {app: ['google chrome', '--incognito']});

api

目标

类型为字符串。
目标通常为你想打开的文件、url或者可执行的文件,一般会用系统中默认的应用打开,当然也可以指定应用以及相关的开启参数。

配置项

类型为对象,object。

  • wait 等待,布尔型
    默认为false,不需要等待。

  • app 指定打开的应用,字符串类型
    windows平台必须设置app,可以设置相关的app启动参数,特殊说明,chrome的指定字符串,
    win : chrome ,mac :google chrome,linux:google-chrome

实践

自己在本地写了一个demo,可以实现这个模块的使用,在使用的时候大家要注意我们除了常规的gulp调用模块之外也可以直接用npm工作流来实现我的需求,在根目录下新建scripts文件夹,写对应的功能js文件,然后在package.json中直接node 执行这个文件即可。

//package.json
  "scripts": {
    "test": "teset",
    "opn": "gulp ",
    "opn2":"node ./scripts/opn"
  },
//gulpfile.js
let gulp = require("gulp")
let opn = require("opn")
let os = require("os")
let uri="http://www.baidu.com"
gulp.task("default",function(){
    let osStr=os.platform()
    if(osStr.indexOf("win")>-1){
        opn(uri, {
            app: ['chrome']
        });
    }

})
// opn.js 
let opn = require("opn")
let os = require("os")
let osStr = os.platform()
let uri = "http://www.baidu.com"
if(osStr.indexOf("win")>-1){
    opn(uri, {
        app: ['chrome']
    });
}

更多探索

我们知道默认的webpack也可以通过dev-server来实现启动浏览器和服务,我们看下它是否也是依赖这个模块实现的呢?

在webpack-dev-server 的模块中,生产依赖中,我们如愿找到了opn的模块依赖,顺便我扒一下它的github托管的源代码,源文件地址:webpack-dev-server,在这个文件中,我们找到了 opn模块的引入以及其对应的使用,在这里我先吧代码搬下来,然后和大家一起分析下与我们的使用有何不同。

代码

const open = require('opn');
if (options.open) {
    let openOptions = {};
    let openMessage = 'Unable to open browser';

    if (typeof options.open === 'string') {
      openOptions = { app: options.open };
      openMessage += `: ${options.open}`;
    }

    open(uri + (options.openPage || ''), openOptions).catch(() => {
      console.log(`${openMessage}. If you are running in a headless environment, please do not use the open flag.`);
    });
  }

代码分析

  • 作为常识我们要知道引入的模块我们一般不会更改的,所以定义用的const,同理大家在定义常量的时候也要注意这点;而在模块内定义的变量尽量用let.
  • 作为常识,我们要知道对象的属性未配置或者配置为undefined 转为布尔均为false的,所以判断其是否配置只需要 options.open即可
  • 一个小功能需要的字段以及提示信息需要在功能开始之前进行定义,比如openOptions,openMessage
  • 针对引入的字段需要做严谨的判断,比如配置项的options.open 的类型,如果存在的话,那么就需要指定对应的app,并修改其报文信息。
  • 针对字符串的拼接尽量引用字符串的模板语法${}
  • 尽可能的简化语法,简单的字符串拼接不用单独定义一个变量,uri + (options.openPage || ''),同时针对配置项的异常情况提供一个默认空字符串
  • 针对模块的使用异常,进行catch捕捉,如果感觉模块本身的报错不够,可以追加自己业务的报错信息。

发布者

Robinson Zhang

热爱前端,热爱分享,坚持高频写作,从小白到大师只是时间问题。

发表评论