npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

reskript

v0.26.7

Published

Finely maintained scripts for react libs and apps

Downloads

43

Readme

reSKRipt

基于react与antd技术栈的命令行工具集合。本工具目标整合Lint、Test、Build、Babel、DevServer等一系列功能,使产品线不再重复性地维护复杂的配置文件及相关脚本。

关于数据采集

reskript默认不进行任何数据的采集,如果支持本工具的开发,可以选择打开。在打开采集后,会采集使用过程中的异常信息,异常信息中将包括:

  • 当前操作系统中的用户名。
  • 当前操作系统类型和版本。
  • 异常发生的详细堆栈,可能由于webpack的异常信息,导致包含一部分的源码。
  • 使用reskript的目标系统的名称,取自package.json中的name字段。

可以设置RESKRIPT_TRACK=on来打开采集功能,如:

RESKRIPT_TRACK=on skr build
# 或使用更全局的环境变量
# export RESKRIPT_TRACK=on
# skr build

安装

要求系统安装node >= 8.9.0版本。

npm install --save-dev reskript

在安装后,会增加一个skr命令。修改项目的package.json中的scripts部分来增加相关功能:

"scripts": {
    "lint": "skr lint",
    "test": "skr test",
    "start": "skr dev",
    "build": "skr build",
    "analyze": "npm run build -- --analyze",
}

以上列出了skr命令的常用功能,如果有定制化要求(如使用build.sh代替简单的skr build),则同样可以调用这些命令完成工作。

自动生成配置文件

使用skr satisfy自动在项目中添加需要的配置文件,并安装相关的依赖。

Usage: satisfy [options]

Satisfy project dependencies

Options:
  --ts            whether this is a typescript project
  --type [value]  your package type, either "app" or "lib" (default: "app")
  --ut [value]    environment of unit test, "node" or "react" (default: "node")
  -h, --help      output usage information

初始化会为项目添加以下内容:

  • 添加webpack.config.js用于WebStorm解析路径,注意这个配置文件不用于实际的构建,仅供IDE参考。
  • 添加eslint的配置,指向reskript指定的规则。
  • 根据--ts参数,添加tsconfig.jsonjsconfig.json
  • 根据--webpack参数自动安装webpack的依赖。
  • 如指定--ut=react,则自动安装enzyme

如果已经手工完成以上步骤,则无需运行此命令进行初始化。

检查代码

使用skr lint检查代码规范。

Usage: lint [options] [files...]

Lint files, by default .js(x) files under src and webpack are linted

Options:
  --changed                    lint only changed files in git workspace
  --staged                     lint only staged (both partially and fully) files in git workspace
  --allow-unsafe-react-method  allow UNSAFE_* methods in react component
  --fix                        fix possible lint errors
  -h, --help                   output usage information

对于新项目,建议直接使用skr lint检查整个项目。遗留项目可以使用skr lint --changed仅检查修改过的文件。同时在Git的pre-commit钩子上使用skr lint --staged来保证入库的代码是符合规范的。

测试

使用skr test测试。

Usage: test [options]

Test

Options:
  --cwd [value] override current working directory (default: process.cwd())
  --coverage  indicates test coverage information
  --watch     watch files for changes and rerun tests related to changed files
  --target [value] specify test environment of the project is "react" or "node" (default: "node")
  --changedSince [value] runs tests related to the changes since the provided branch. (default: '')
  -h, --help  output usage information

skr test会自动搜索所有 .test.js 结尾的文件运行,建议的文件结构为

/__tests__
    * util.test.js
util.js

然后在 util.test.js

import {add} from '../util';

describe('add', () => {
    test('1 + 2 = 3', () => {
        expect(add(1, 2)).toBe(3);
    })
})

CHANGE: 0.25.17 之后

  1. 不再支持相对路径的src目录参数,resolve src只是cwd下面的src目录。影响是:只可以在eefe root目录级别运行skr test,才能正确resolve @/ 到 src/ 下面

  2. 添加了根据项目里的jest.config.js来配置jest的能力。

  • 如果项目中有jest.config.js,需要指定reskript/config/jest-react.js的相对路径(根据当前项目)来引入skr test的默认配置。例如:'./node_modules/reskript/config/jest-react.js'。 如果使用require.resolve('reskript/config/jest-react.js'),需要变成相对目录,'./' + path.relative('', require.resolve('reskript/config/jest-react.js')), 前面的 ./ 是需要的。 如果是react,引用jest-react.js,如果是node,引用jest-node.js
  • 如果项目中没有jest.config.js,skr test会用默认配置(与preset相同) 注意: 如果用了jest.config.js,settings下面的test值将不起作用。

实时预览组件

使用skr play可以打开一个实时编辑页面,用于测试及预览指定的组件。

Usage: play [options] <target>

Start a playground to debug a certain component

Options:
  --cwd [value]           override current working directory (default: process.cwd()")
  --build-target [value]  set build target, default to "dev" (default: "dev")
  -h, --help              output usage information

如执行skr play src/components/UserInfo/index.js后,则会进行自动构建,随后可在http://localhost:9999中打开实时预览页面,页面左侧可编辑代码,右侧进行实时的预览。

打包基础库

使用skr rollup来对基础库(非业务系统)进行打包,底层使用rollup实现。

Usage: rollup [options]

Build entire app

Options:
  --cwd [value]   override current working directory (default: process.cwd())
  --mode [value]  set build mode, default to "production" (default: "production")
  --clean         remove dist directory before build
  -h, --help      output usage information

可以在settings.js中导出rollup对象,允许有以下属性:

  • {Object} namedDependencyExports:指定第三方库的命名导出,具体参考rollup-plugin-commonjs的说明
  • {string} styleOutput:指定样式的输出格式,为"inject"时内置到JavaScript中,为"extract"时输出为与JavaScript同名的.css文件,为"index"时输出为单个style/index.css文件,默认值为"index"
  • {string} target:指定编译的目标平台,为"web""node""universal",默认为"universal"。指定"web"时仅用于浏览器,但可以基于此做一些优化,如移除node模块的依赖。

除此以外,当前版本不暴露任何配置,封闭了eslintbabelpostcss等能力。

构建系统

基础目录结构

构建系统对目录结构有一定要求,必须包含以下部分:

/src
    /styles
        *.global.less # .global.less文件不会经过CSS Modules编译,可放置一些全局的样式
        *.var.less # .var.less会被提取作为LESS编译时的变量,内部仅可声明变量(以及注释)
    /entries
        index.js # 主入口
settings.js # 系统配置文件

其中*.global.less事实上可以放置在任意位置,只要是以.global.less结尾的,均不会经过CSS Modules处理。

默认.less文件内可直接使用EST插件提供的内容,其它相关loader的配置请直接参考源码,不再赘述。

特殊文件命名

以下是可用的一系列特殊处理的文件命名规则:

  • *.global.less:定义全局的样式,不会经过CSS Modules处理。
  • *.worker.js:定义Web Worker,会被编译成一个Worker类。

全局变量

在源码中可以使用以下的全局变量(通过DefinePlugin提供):

  • process.env.XXX:对应环境变量中的值。
  • $features.xxx:对应Feature Matrix中的特性值。
  • $build.mode:构建时的mode值,建议使用这个变量来代替process.env.NODE_ENV
  • $build.version:当前构建的版本号。
  • $build.target:当前构建的目标。
  • $build.time:当前构建的时间,为ISO格式字符串。

以上全局变量可直接使用,不会被lint功能认为错误。

系统配置

对于业务系统,必须在项目根目录下放置一个settings.js,该文件为项目的整体配置,需导出featureMatrixbuilddevServeradditionplugins共五项。基础库也可通过settings.js(可选)导出rollup用于第三方库的构建,但与系统的构建无关,参考前文:

Feature Matrix

除第三方库类型的项目外,要求所有系统使用Feature Matrix维护源码,避免Feature分支开发导致的合入困难问题。

settings.js导出featureMatrix对象,该对象的每一个属性均代表一个Feature集合。

一个项目必须至少包含以下3个Feature集合:

  • stable:用于全流量。
  • insiders:用于小流量。
  • dev:用于开发。

以上3个集合为必须,其中dev仅在开发过程使用。如果系统本身没有灰度机制,可以使用最简单的模板:

exports.featureMatrix = {
    stable: {},
    insiders: {},
    dev: {}
};

构建配置

settings.js导出builld对象,可以包含以下属性:

  • {boolean} thirdParty:是否以第三方库的形式构建,第三方库的构建不使用featureMatrix、不拆分chunk,同时构建产出不带hash、不产出HTML文件。
  • {boolean} reportLintErrors:构建过程中检查代码规范,默认值为true。如无特殊原因,禁止关闭这个开关。
  • {boolean} extractCSS:是否将CSS抽取到独立的.css文件中,默认为true,当CSS的顺序有问题,或者构建第三方库时,可以选择设置为false
  • {Condition} noCompileScripts:无需经过babel编译的JavaScript文件列表,仅包含项目源码部分,不要包含第三方的库。
  • {Condition} noModulesStyles:无需经过CSS Modules处理的样式文件列表,仅包含项目源码部分,不要包含第三方的库。如果整个系统没有使用CSS Modules,则该配置的值可以为[() => true]
  • {string[]} styleResources:用于编译LESS的变量资源文件列表。每个文件均会被注入到所有的LESS文件前面,作为全局可用的资源。
  • {number} largeAssetSize:生成静态文件的限值,以字节为单位。小于该值的会被编译为DataURI内联,大于该值的会变为单独的文件。默认值为8KB
  • {Object} browserSupport:支持的浏览器范围,用于babel-preset-env
  • {boolean} styleName:是否使用styleName来调用CSS Modules,默认为true
  • {boolean} polyfill:是否自动引入core-js的相应polyfill,默认为true。如果你使用了其它方式引入polyfill,设置为false即可。
  • {string} extraLessPaths:LESS中@import的查找路径,默认为src, node_modules, src/styles这三个目录。
  • {string} cssScope:给所有的CSS选择器加上一个作用域,如该属性值为#foo,则header > .navigation会变为#foo header > .navigation
  • {Object[]} copies:需要进行复制的静态文件列表,用于copy-webpack-plugin
  • {string} appTitle:应用的标题,用于生成<title>元素。
  • {string} favicon:favicon的位置。
  • {string[]} excludeFeatures:构建过程中需要排除的Feature名称,默认排除['dev'],其它均会被构建。
  • {boolean} autoRouteSplit:自动根据路由进行code split,具体参考自动路由拆分章节。

调试服务器

settings.js导出devServer对象,可包含以下属性:

  • {number} port:启动的端口。
  • {string[]} apiPrefixes:需要代理的API请求的前缀,如['/rest', '/api']则会将所有/rest/api的请求代理至后端。
  • {string} defaultProxyDomain:默认的后端域名,仅需填写域名部分(如engmapbeta.baidu.com),可以被--proxy-domain参数覆盖。
  • {string} hot:是否启用HMR,可选值为nonesimpleall。使用none时禁用HMR;为simple时开启简单的HMR,仅对样式等资源生效;为all时开启hotOnly配置,并自动打开React的HMR。

入口页配置

构建或调试允许定制入口页,也允许单系统多入口。

系统必须有src/entries这个目录,其下放置所有的入口文件,默认的名称为index。每一个入口对应以下文件:

  • [name].js:入口的启动脚本。
  • [name].ejs:HTML模板,以EJS作为模板格式,如果一个入口不存在对应的.ejs文件,则会使用默认的模板。自定义模板可使用htmlWebpackPlugin.options.buildIdentifier获取构建版本号。
  • [name].config.js:生成入口页面的额外配置,这个文件的module.exports对象会直接传递给html-webpack-plugin,可以定制化页面信息,也可以将额外的数据传递给[name].ejs模板。

例如某个入口页面的<title>希望得到修改,则可以在[name].config.js中这样写:

module.exports = {
    title: '定制化的标题'
};

入口页的模板([name].ejs)或配置文件([name].config.js)修改后,需要手动重启调试,当前版本并不会自动监听这些文件。

额外配置

settings.js导出addition函数,该函数将接受一个构建时的环境对象,并返回一部分webpack配置。

当由addition函数返回的配置中包含module.rules时,自定义的module.rules将完全覆盖默认的配置(不会做任何的合并策略),其它的配置项则会通过webpack-merge与默认的配置合并。

所谓构建时的环境对象,即通过build导出的对象,外加通过命令行提供的参数。通常来说,其中的mode属性是最为重要的。

默认配置

以下为一个常见的默认配置,仅供参考:

exports.featureMatrix = {
    stable: {},
    insiders: {},
    dev: {}
};

exports.build = {
    appTitle: 'React App', // 修改为应用的名称
};

exports.devServer = {
    port: 8078, // 修改为不与其它应用重复的端口号
    apiPrefixes: ['/api'],
    defaultProxyDomain: '', // 修改为测试环境地址
    uuapCallbackURL: '/',
    presetUsers: [] // 添加模块登录的预置用户
};

exports.addition = () => ({});

使用插件

settings.js导出plugins数组,数组中的每一项为一个函数,函数接受settings.js导出的{featureMatrix, build, devServer, addition}对象和当前命令行参数,并返回一个相同的对象。

插件会按顺序被依次调用,最终返回的对象用于各种功能。

构建产物

构建输出到dist目录,所有静态资源放置于dist/assets目录下,入口HTML页面放置于dist目录下。基于Feature Matrix进行构建后,不同Feature集产生的文件也都混合在一起,无需分隔为不同目录。

在Feature Matrix的模式下,线上分流需要按照HTML文件名分流,如主流量分到stable.html上,小流量则分到insiders.html上。而dist/assets目录则不需要设置鉴权,以便Sentry或Firefox等应用在无Cookie的情况下可以成功下载到Source Map。

如果当前系统线上无法基于HTML文件名分流,则参考“启动构建”章节使用--build-target参数进行兼容。

启动构建

使用skr build构建整个系统。

Usage: build [options]

Build entire app

Options:
  --cwd [value]           override current working directory (default: process.cwd())
  --mode [value]          set build mode, default to "production" (default: "production")
  --src [value]           specify the dir containing source files relative to cwd (default: "src")
  --build-target [value]  create index.html according to specific target
  --analyze               enable bundle analysis
  --clean                 remove dist directory before build
  -h, --help              output usage information

默认基于Feature Matrix构建,需要线上的Nginx等服务器配合分流。如果没有这一能力,则需要指定--build-target参数,该参数指定的Feature集合的构建结果会被复制为index.html,以便上线部署时不会出错。

打开调试服务器

使用skr dev启动调试服务器,初次构建完成后会自动打开网页。

Usage: dev [options]

Start dev server for debugging

Options:
  --cwd [value]            override current working directory (default: process.cwd())
  --mode [value]           set build mode, default to "development" (default: "development")
  --src [value]            specify the dir containing source files relative to cwd (default: "src")
  --build-target [value]   set build target, default to "dev" (default: "dev")
  --proxy-domain [domain]  set api proxy domain, only domain part (www.example.com) is required
  -h, --help               output usage information

在调试过程中,会监听settings.js的变更并重启调试服务器,重启后不会自动打开网页。

自动路由拆分

settings.js中的``exports.build.autoRouteSplit属性为true`时,会启用自动路由拆分,该逻辑会找到合适的拆分点,要求需要满足以下条件:

  1. 组件被使用在<TrackRoute components>属性上,如<TrackRoute exact path="/admin" components={AdminPage} />
  2. 对应的组件必须是默认引入的,即import AdminPage from '../AdminPage'的形式。
  3. 必须配合@ecomfe/react-track使用。

在满足以上条件时,如下代码:

import AdminPage from '../AdminPage';

<TrackRoute exact path="/admin" component={AdminPage} />

会被编译为:

import {lazy} from 'react';

const LazyAdminPage = lazy(() => import('../AdminPage'));
<TrackRoute exact wrapSuspense path="/admin" component={LazyAdminPage} />

以此获得webpack的code split能力。由于lazy后的组件必须搭配Suspense使用,所以依赖@ecomfe/react-trackTrackRoute组件支持(内部自动添加Suspense)。

当前无法保证此功能100%满足场景,开启后请小心测试。

定制化构建

如果默认的构建配置外加settings.js无法满足,或需要在settings.js中的addition部分复用一些默认的配置,则可以使用reskript提供的函数辅助创建loader相关的配置。

复用loader

reskript导出loaders对象,内含了生成常用loader配置的函数,包括:

  • babel({cwd, mode, browserSupport, ui, styleName})
  • css({mode})
  • cssModules({mode})
  • eslint({mode})
  • less({mode, cwd, extraLessVariables, extraLessPaths})
  • postCSS({mode, cssScope, lint}, {external = false} = {})
  • styleResources({cwd})
  • sourceMap()
  • style({mode})
  • img({mode})
  • url({largeAssetSize})
  • typescript({mode})

以上函数的相关配置均参考构建配置的对应字段。

复用规则

如果在复用loader的情况下,还希望复用module.rules的相关规则,reskript导出rules对象,包括:

  • script(env)
  • less(env)
  • css(env)
  • image(env)
  • file(env)
  • typescript(env)

以上函数均需要一个完成的配置对象(env)作为参数,该对象即settings.js中的addition函数接收的参数。

对于需要修改某一个规则的情况,建议在rules的基础上移除需要修改的规则后全部应用,再增加自定义规则。如某个项目需要将.css文件的规则修改,则可以如下配置:

const {omit} = require('lodash');
const {rules} = require('reskript');

exports.addition = env => {
    // 先移除css的规则
    const baseRules = Object.values(omit(rules, ['css'])).map(rule => rule(env));

    return {
        module: {
            rules: [
                ...baseRules,
                {
                    test: /\.css$/,
                    use: [...]
                }
            ]
        }
    };
};

reskript无法保证每一次升级时在rules对象上保持完全的向后兼容,如上的写法可比较灵活地应对升级导致的规则的增减。

获取webpack配置

为了方便与其它工具如react-styleguidist进行整合,reskript允许通过程序获取webpack的配置。使用createBuildConfig(env)createDevConfig(env)函数分别获取完整构建或者开发调试用的配置对象。

其中env对象必需包含以下属性:

  • {Object} projectSettings:来自settings.js的对象,通常使用require('./settings')获取即可,具体结构见前文描述。
  • {string} mode:构建的形式,为developmentproduction
  • {string} usage:构建使用场景,为build(构建产出结果)或devServer(开发调试服务器)。

其它可选属性参考builddev命令的帮助文档,所有命令行参数均可在camelCase化后作为env对象的属性传入。

辅助排查

skr命令出现不符合预期的问题时,它很有可能是因为间接依赖的第三方包导致的。由于reskript并不使用shrinkwrap机制锁定版本,因此需要导出所有第三方依赖的版本来确定问题。使用skr doctor可以得到排查问题的相关信息:

Usage: doctor [options]

Collect debug information for et itself

Options:
  --cwd [value]  override current working directory
  --json         print result in JSON format
  -h, --help     output usage information

通常使用skr doctor | pbcopy可将结果复制到剪贴板中。

对于新项目,建议直接使用skr lint检查整个项目。遗留项目可以使用skr lint --changed仅检查修改过的文件。同时在Git的pre-commit钩子上使用skr lint --staged来保证入库的代码是符合规范的。

TODO

  • 支持DLL:等autodll-webpack-plugin升级后实现。