docs/react-v9/contributing/rfcs/shared/build-system/03-packaging-for-npm.md
List contributors to the proposal here: @hotell
💡 NOTE: This proposal/guide applies only for vNext packages and libraries using new DX
We ship unnecessary things to our consumers:
.d.ts)💡 NOTE: This proposal/guide applies only for vNext packages and libraries using new DX
This is a living document that will describe various proposals that all aim to improve following common goals:
.npmignore cleanup (implemented)What we ship is driven by our current npm package setup, which looks like following:
<package>/.npmignore
*.api.json
*.config.js
*.log
*.nuspec
*.test.*
*.yml
.editorconfig
.eslintrc*
.eslintcache
.gitattributes
.gitignore
.vscode
coverage
dist/storybook
dist/*.stats.html
dist/*.stats.json
dist/demo
fabric-test*
gulpfile.js
images
index.html
jsconfig.json
node_modules
results
src/**/*
!src/**/examples/*.tsx
!src/**/docs/**/*.md
!src/**/*.types.ts
temp
tsconfig.json
tsd.json
tslint.json
typings
visualtests
NOTE: data was acquired by running
npm pack --dry-runinpackages/react-text
Packaged output:
=== Tarball Details ===
name: @fluentui/react-text
version: 9.0.0-alpha.0
package size: 564.2 kB
unpacked size: 2.2 MB
total files: 1008
With manually removed .cache folder:
=== Tarball Details ===
name: @fluentui/react-text
version: 9.0.0-alpha.0
package size: 31.1 kB
unpacked size: 263.9 kB
total files: 518
NOTE: The issue with
.cache(Jest cache) was addressed separately by moving the cache under<package root>/node_modules/.cache/jest, following the convention used by other tools' caches.
update .npmignore to following setup:
<package>/.npmignore
.storybook/
.vscode/
bundle-size/
config/
coverage/
e2e/
etc/
node_modules/
src/
dist/types
temp/
__fixtures__
__mocks__
__tests__
*.api.json
*.log
*.spec.*
*.stories.*
*.test.*
*.yml
# config files
*config.*
*rc.*
.editorconfig
.eslint*
.git*
.prettierignore
NOTE: data was acquired by running
npm pack --dry-runinpackages/react-text
Packaged output:
=== Tarball Details ===
name: @fluentui/react-text
version: 9.0.0-alpha.0
package size: 24.7 kB
unpacked size: 172.8 kB
total files: 250
This approach significantly improves our current situation:
npmignore configuration / better maintenance"files" withing package.json
files property is used, some files will be automatically and always shipped).npmignore and files)To be able to provide TypeScript support to our consumers we generate declaration files during tsc invocation.
These declaration files are:
Aforementioned approach introduces 2 problems.
Problem 1: generated side by side with implementation files
Problem 2: generated N times for N supported module loaders
module field, thus this generation is redundant and provides no benefit.Example:
module: CommonJs
import type { FunctionComponent } from 'react';
import { TextWrapperProps } from '../wrapper';
export declare const bodyClassName = 'fui-Body';
export declare const Body: FunctionComponent<TextWrapperProps>;
module: ESM
import type { FunctionComponent } from 'react';
import { TextWrapperProps } from '../wrapper';
export declare const bodyClassName = 'fui-Body';
export declare const Body: FunctionComponent<TextWrapperProps>;
Problem 1 solution:
.d.ts for all public API entrances. We can leverage already existing setup via api-extractor.Execution flow will look like following:
New build output structure will look like following:
|- <package-name>/
|- dist/
|- |- index.d.ts # rolluped declaration file
|- lib/ # module: ESNext
|- |- *.js
|- |- *.map.js
|- lib-commonjs/ # module: CommonJS
|- |- *.js
|- |- *.map.js
|- package.json
Problem 2 solution:
declaration generation only once during build.NOTE: to make this RFC more focused this will be covered in followup PR's if needed
NOTE: to make this RFC more focused this will be covered in followup PR's if needed