配置解密
本章节会简单地介绍各个环节的配置,你可以从这里发现reSKRipt做的工作和带来的功能,不过我们也不保证这里说明的和最新的实现是完全同步的。
并且,我们不希望你依赖这边描述的内部配置来实现业务,我们不确定每次更新不会影响内部的逻辑。
Babel相关
core-js
默认使用useBuiltins: 'usage'来引入core-js,你需要自行安装core-js的3.x版本。
组件名称
所有的React组件会给加上displayName,支持函数定义形式的组件,任何函数定义名称为PascalCase均被认为是组件:
function FooBar() {
    return <div />;
}
组件的displayName会以函数名为准。
组件源码路径
在进行应用调试时,经常会遇到这样一个情况:虽然找到了一个React组件,但一时对应不上哪个源代码文件里实现了这个文件。考虑到组件层级较深时,经常有一些局部使用的同名组件,比如大家都叫Content,就很尴尬,用displayName也不容易定位。
为此reSKRipt在开发模式下会为每一个组件注入一些代码,你可以在React Devtools中看到这个组件对应的源码文件:

note
所有与组件相关的额外能力,均只支持函数定义形式的组件,即function FooBar() {}的形式。其它如函数表达式、箭头函数都均不支持。
语法支持
支持以下新语法:
- export Foo from './Foo'
- export {Foo} from './Foo'
- const foo = obejct.foo ?? 'default'
- 1_234_567
- object?.foo?.bar
- const result = array |> unique |> compact |> flatten
- const valid = input.isValid() || throw new Error('Invalid')
代码删减
对lodash和antd的引入会做优化处理,转成只引入用到的部分。
在mode=production的情况下,会把组件的propTypes删掉。
Webpack相关
缓存
无论是build还是dev,都会把缓存写到文件系统中(这可以让skr dev打开无比迅速),以下内容会参与到缓存的key的计算中:
- package.json的内容。
- 项目配置文件的路径。
- 项目配置文件的内容。
- package-lock.json、- yarn.lock或- pnpm-lock.yaml的内容。
- .browserslistrc的内容。
- 执行的命令,即build或dev之类的。
- 当前的mode,即production或development。
- 当前的包名,即package.json中的name字段。
- 当前的目录,即process.cwd()。
缓存会放在node_modules/.cache/webpack下,以{command}-{mode}命名,比如dev-server-development。
在build命令时,文件的哈希用来校验该文件是否变更(比较慢),而在dev时则用文件的时间戳(比较快)。这么做是因为CI/CD环境会每次都全新git clone一份代码,导致时间戳总是不一样的,没办法用上缓存。
文件支持
只认.js、.jsx、.ts、.tsx这几类文件作为脚本。
引入包时的主字段的顺序是browser -> module -> main,所以浏览器兼容的实现会被优先引入。
设置了@/别名指向src/。
环境变量
process.env中的所有内容都通过DefinePlugin注入了,可以直接以process.env.FOO_BAR的形式来使用。
在特性矩阵中有说过,所有声明在项目配置文件里的featureMatrix中的东西,都可以用skr.features.fooBar来拿到,这也是用DefinePlugin来实现的。
另外你还能用skr.build.前缀来拿到当前构建的一些元信息,这个元信息的结构大致如下:
interface BuildInfo {
    mode: 'production' | 'development';
    version: string; // 有git的情况下是git的commit
    target: string; // 对应特性名称
    time: string; // 触发的时间,ISO格式
}
你不能直接用skr.build对象哦,必须用skr.build.version这样的常量才会被替换。
严格模式
在skr build和skr dev中使用--strict参数后,会进入严格模式,严格模式下将额外增加以下检测:
- 会检查import中路径大小写是否正确,即便你是大小写不敏感的操作系统(比如Windows和macOS),也会检查出来。
- 全局禁用require.ensure、require.context、require.include方法,即不再支持CommonJS的动态依赖。
- 如果你的当前目录有tsconfig.json文件,则会进行类型检查。这一功能仅在skr build时生效,skr dev默认关闭。
其它优化
对于moment的本地化语言包有特殊处理,会只引入en和zh-CN两个,所以你要支持其它语言就比较折腾了,可以提个issue来问。
react和react-dom会根据当前的mode选择不同的文件,算是非常标准的优化项。
如果src/service-worker.js中有`self.__WB_MANIFEST字样,使用workbox-webpack-plugin的InjectManifest注入资源路径。
会自动向生成的HTML中注入navigator.serviceWorker.register相关的代码。
调试服务器
文件监听
当reSKRipt配置文件有变化(实际内容有变化)时,服务器会重启。因为这个变化基本肯定也会影响缓存的key,所以这次重启是比较慢的,请耐心等待。
node_modules下的东西默认不监听变化,有需要的请参考配置的文档来修改配置。记得调试完第三方包后改回去,不然内存爆炸。
History API
虽然reSKRipt支持多入口,但在调试的时候默认只能拿到index这个入口。
如果你要访问其它入口,可以/assets/xxx-stable.html这样来访问,但至于这会不会让路由出错,也不好说了。
现在没找到一个很好的办法支持多入口又能完美使用History API,有啥办法欢迎在issue中指出。