Skip to main content

配置解密

本章节会简单地介绍各个环节的配置,你可以从这里发现reSKRipt做的工作和带来的功能,不过我们也不保证这里说明的和最新的实现是完全同步的。

并且,我们不希望你依赖这边描述的内部配置来实现业务,我们不确定每次更新不会影响内部的逻辑。

Babel相关

core-js

默认使用useBuiltins: 'usage'来引入core-js,你需要自行安装core-js3.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')

代码删减

lodashantd的引入会做优化处理,转成只引入用到的部分。

mode=production的情况下,会把组件的propTypes删掉。

Webpack相关

缓存

无论是build还是dev,都会把缓存写到文件系统中(这可以让skr dev打开无比迅速),以下内容会参与到缓存的key的计算中:

  • package.json的内容。
  • 项目配置文件的路径。
  • 项目配置文件的内容。
  • package-lock.jsonyarn.lockpnpm-lock.yaml的内容。
  • .browserslistrc的内容。
  • 执行的命令,即builddev之类的。
  • 当前的mode,即productiondevelopment
  • 当前的包名,即package.json中的name字段。
  • 当前的目录,即process.cwd()

缓存会放在node_modules/.cache/webpack下,以{command}-{mode}命名,比如dev-server-development

build命令时,文件的哈希用来校验该文件是否变更(比较慢),而在dev时则用文件的时间戳(比较快)。这么做是因为CI/CD环境会每次都全新git clone一份代码,导致时间戳总是不一样的,没办法用上缓存。

文件支持

只认.js.jsx.ts.tsx.d.ts这几类文件作为脚本。

引入包时的主字段的顺序是browser -> module -> main,所以浏览器兼容的实现会被优先引入。

设置了@/别名指向src/

环境变量

process.env中的所有内容都通过DefinePlugin注入了,可以直接以process.env.FOO_BAR的形式来使用。

特性矩阵中有说过,所有声明在项目配置文件里的featureMatrix中的东西,都可以用$features.fooBar来拿到,这也是用DefinePlugin来实现的。

另外你还能用$build.前缀来拿到当前构建的一些元信息,这个元信息的结构大致如下:

interface BuildInfo {
mode: 'production' | 'development';
version: string; // 有git的情况下是git的commit
target: string; // 对应特性名称
time: string; // 触发的时间,ISO格式
}

你不能直接用$build对象哦,必须用$build.version这样的常量才会被替换

严格模式

skr buildskr dev中使用--strict参数后,会进入严格模式,严格模式下将额外增加以下检测:

  1. 会检查import中路径大小写是否正确,即便你是大小写不敏感的操作系统(比如Windows和macOS),也会检查出来。
  2. 全局禁用require.ensurerequire.contextrequire.include方法,即不再支持CommonJS的动态依赖。
  3. 如果你的当前目录有tsconfig.json文件,则会进行类型检查。这一功能仅在skr build时生效,skr dev默认关闭

其它优化

对于moment的本地化语言包有特殊处理,会只引入enzh-CN两个,所以你要支持其它语言就比较折腾了,可以提个issue来问。

reactreact-dom会根据当前的mode选择不同的文件,算是非常标准的优化项。

如果src/service-worker.js中有`self.__WB_MANIFEST字样,使用workbox-webpack-pluginInjectManifest注入资源路径。

会自动向生成的HTML中注入navigator.serviceWorker.register相关的代码。

调试服务器

文件监听

reSKRipt配置文件有变化(实际内容有变化)时,服务器会重启。因为这个变化基本肯定也会影响缓存的key,所以这次重启是比较慢的,请耐心等待。

node_modules下的东西默认不监听变化,有需要的请参考配置的文档来修改配置。记得调试完第三方包后改回去,不然内存爆炸。

History API

虽然reSKRipt支持多入口,但在调试的时候默认只能拿到index这个入口。

如果你要访问其它入口,可以/assets/xxx-stable.html这样来访问,但至于这会不会让路由出错,也不好说了。

现在没找到一个很好的办法支持多入口又能完美使用History API,有啥办法欢迎在issue中指出。