-
-
Notifications
You must be signed in to change notification settings - Fork 57
docs: update structure / format / 3rd deps / glossary / TS #357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,6 +131,7 @@ unencapsulated | |
| unocss | ||
| unpatch | ||
| unplugin | ||
| unpredictibly | ||
| unshift | ||
| upath | ||
| vitest | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| [ | ||
| "package-json", | ||
| "templates", | ||
| "third-party-deps", | ||
| "polyfill", | ||
| "css", | ||
|
|
||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,81 @@ | ||
| # Handle Third-party Dependencies | ||
|
|
||
| Generally, third-party dependencies required by a project can be installed via the `install` command in the package manager. After the third-party dependencies are successfully installed, they will generally appear under `dependencies` and `devDependencies` in the project `package.json`. | ||
|
|
||
| ```json title="package.json" | ||
| { | ||
| "dependencies": {}, | ||
| "devDependencies": {} | ||
| } | ||
| ``` | ||
|
|
||
| Dependencies under `"dependencies"` are generally related to project code and builds, and if these third-party dependencies are declared under `"devDependencies"`, then there will be missing dependencies in production runtime. | ||
|
|
||
| In addition to `"dependencies"`, `"peerDependencies"`can also declare dependencies that are needed in the production environment, but it puts more emphasis on the existence of these dependencies declared by `"peerDependencies"` in the project's runtime environment, similar to the plugin mechanism. | ||
|
|
||
| ## Default handling of third-party dependencies | ||
|
|
||
| By default, **third-party dependencies under `"dependencies"`, `"optionalDependencies"` and `"peerDependencies"` are not bundled by Rslib**. | ||
|
|
||
| This is because when the npm package is installed, its `"dependencies"` will also be installed. By not packaging `"dependencies"`, you can reduce the size of the package product. | ||
|
|
||
| If you need to package some dependencies, it is recommended to move them from `"dependencies"` to `"devDependencies"`, which is equivalent to **prebundle** the dependencies and reduces the size of the dependency installation. | ||
|
|
||
| ### Example | ||
|
|
||
| If the project has a dependency on `react`. | ||
|
|
||
| ```json title="package.json" | ||
| { | ||
| "dependencies": { | ||
| "react": "^18" | ||
| }, | ||
| // or | ||
| "peerDependencies": { | ||
| "react": "^18" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| When a `react` dependency is used in the source code: | ||
|
|
||
| ```tsx title="src/index.ts" | ||
| import React from 'react'; | ||
| console.info(React); | ||
| ``` | ||
|
|
||
| The `react` code will not be bundled into the output: | ||
|
|
||
| ```js title="dist/index.js" | ||
| import * as __WEBPACK_EXTERNAL_MODULE_react__ from 'react'; | ||
| console.info(__WEBPACK_EXTERNAL_MODULE_react__['default']); | ||
| ``` | ||
|
|
||
| If you want to modify the default processing, you can use the following API. | ||
|
|
||
| - [`lib.autoExternal`](/config/lib/auto-external) | ||
|
|
||
| ## Exclude specified third-party dependencies | ||
|
|
||
| We previously introduced the use of [`lib.autoExternal`](/config/lib/auto-external). This configuration lets you manage third-party dependencies more precisely. | ||
|
|
||
| For example, when we need to leave only certain dependencies unbundled, we can configure it as follows. | ||
|
|
||
| :::tip | ||
| In this case, some dependencies may not be suitable for bundling. If so, you can handle it as follows. | ||
| ::: | ||
|
|
||
| ```ts | ||
| export default defineConfig({ | ||
| lib: [ | ||
| { | ||
| // ... | ||
| autoExternal: true, | ||
| output: { | ||
| externals: ['pkg-1', /pkg-2/], | ||
| }, | ||
| // ... | ||
| }, | ||
| ], | ||
| }); | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,9 @@ | ||
| [ | ||
| "cli", | ||
| "configure-rslib", | ||
| "typescript-usage", | ||
| "output-files", | ||
| "bundle-mode", | ||
| "typescript", | ||
| "output-format", | ||
| "output-structure", | ||
| "upgrade-rslib", | ||
| "cjs-esm", | ||
| "umd" | ||
| ] |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| import ESM from '../start/components/ESM.mdx'; | ||
| import CJS from '../start/components/CJS.mdx'; | ||
| import UMD from '../start/components/UMD.mdx'; | ||
|
|
||
| # Output Format | ||
|
|
||
| This sets the output format for the generated JavaScript files. There are three supported values now: `esm`, `cjs`, and `umd`. In this guide, we will discuss the differences between these formats and how to choose the right one for your library. | ||
|
|
||
| ## ESM / CJS | ||
|
|
||
| Library authors need to carefully consider which module formats to support. Let's understand ESM (ECMAScript Modules) and CJS (CommonJS) and when to use them. | ||
|
|
||
| ### What are ESM and CJS? | ||
|
|
||
| <ESM /> | ||
|
|
||
| - **ESM**: ESM is <ESM /> | ||
|
|
||
| - **CommonJS**: [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules) is <CJS /> | ||
|
|
||
| ### What is the dilemma of esm / cjs | ||
|
|
||
| > The following references are from [Node Modules at War: Why CommonJS and ES Modules Can't Get Along](https://redfin.engineering/node-modules-at-war-why-commonjs-and-es-modules-cant-get-along-9617135eeca1). | ||
|
|
||
| 1. You can't `require()` ESM scripts; you can only import ESM scripts, like this: `import {foo} from 'foo'` | ||
| 2. CJS scripts can't use static `import` statements like the one above. | ||
| 3. ESM scripts can `import` CJS scripts, but only by using the “default import” syntax `import _ from 'lodash'`, not the “named import” syntax `import {shuffle} from 'lodash'`, which is a hassle if the CJS script uses named exports. (Except, sometimes, unpredictibly, Node can figure out what you meant!) | ||
| 4. ESM scripts can `require()` CJS scripts, even with named exports, but it's typically not worth the trouble, because it requires even more boilerplate, and, worst of all, bundlers like Webpack and Rollup don't/won't know how to work with ESM scripts that use `require()`. | ||
| 5. CJS is the default; you have to opt-in to ESM mode. You can opt-in to ESM mode by renaming your script from `.js` to `.mjs`. Alternately, you can set `"type": "module"` in `package.json`, and then you can opt-out of ESM by renaming scripts from `.js` to `.cjs`. (You can even tweak just an individual subdirectory by putting a one-line `{"type": "module"}` `package.json` file in there.) | ||
|
|
||
| ### When to support which format? | ||
|
|
||
| For different shapes of libraries, the choice of module format may vary. Here are two common scenarios: | ||
|
|
||
| #### ship [pure ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package. | ||
|
|
||
| shipping only ESM is the best choice for libraries that are intended to be used in modern environments, such as browser applications or Node.js applications that support ESM. However, if the upstream library is in format of CJS, they only can import pure ESM by using dynamic import like `const pureEsmLib = await import('pure-esm-lib')`. | ||
|
|
||
| - **Pros:** | ||
| - ESM is the official JavaScript standard, making it more future-proof and widely supported across environments. | ||
| - ESM enables static analysis, which facilitates optimizations like tree-shaking to remove unused code. | ||
| - The syntax is cleaner and more intuitive, with import and export statements that are easier to read compared to CommonJS. | ||
| - ESM allows for better compatibility across both browser and server environments, making it ideal for isomorphic or universal JavaScript applications. | ||
| - **Cons:** | ||
| - ESM modules are loaded asynchronously, which can complicate conditional imports and lazy loading in some cases. | ||
| - Some Node.js tools and libraries still have limited or incomplete support for ESM, requiring workarounds or additional configuration. | ||
| - You must explicitly include file extensions in import paths, which can be cumbersome, especially when working with TypeScript or other transpiled languages. | ||
|
|
||
| #### ship [ESM & CJS (dual)](https://antfu.me/posts/publish-esm-and-cjs#compatibility) package. | ||
|
|
||
| The community is migrating to ESM, but there are still many projects using CJS. If you want to support both ESM and CJS, you can publish a dual package. For most library authors, offering dual formats is a safer and smoother way to access the best of both worlds. You could read antfu' blog post [Publish ESM and CJS packages](https://antfu.me/posts/publish-esm-and-cjs) for more details. | ||
|
|
||
| - **Pros:** | ||
|
|
||
| - Wider compatibility: Dual packages support both modern ESM environments and legacy CJS environments, ensuring broader usage across different ecosystems. | ||
| - Gradual migration: Developers can gradually transition from CJS to ESM without breaking existing projects, allowing for smoother adoption of the new standard. | ||
| - Flexibility for consumers: Users of the package can choose which module system best fits their project, providing flexibility in different build tools and environments. | ||
| - Cross-runtime support: Dual packages can work in multiple runtimes, such as Node.js and browsers, without requiring additional bundling or transpilation. | ||
|
|
||
| - **Cons:** | ||
|
|
||
| - Increased complexity: Maintaining two module formats adds complexity to the build process, requiring additional configuration and testing to ensure both versions work correctly14. | ||
| - Dual package hazard: Mixing ESM and CJS can lead to issues such as broken instanceof checks or unexpected behavior when dependencies are loaded in different formats13. | ||
|
|
||
| ## UMD | ||
|
|
||
| <UMD /> | ||
|
|
||
| ### When to use UMD? | ||
|
|
||
| If you are building a library that needs to be used in both the browser and Node.js environments, UMD is a good choice. UMD can be used as a standalone script tag in the browser or as a CommonJS module in Node.js. | ||
|
|
||
| A detailed answer from StackOverflow: [What is the Universal Module Definition (UMD)?](https://stackoverflow.com/a/77284527/8063488) | ||
|
|
||
| > However, for frontend libraries, you still offer a single file for convenience, that users can download (from a CDN) and directly embed in their web pages. This still commonly employs a UMD pattern, it's just no longer written/copied by the library author into their source code, but added automatically by the transpiler/bundler. | ||
| > | ||
| > And similarly, for backend/universal libraries that are supposed to work in | ||
| > node.js, you still also distribute a commonjs module build via npm to support | ||
| > all the users who still use a legacy version of node.js (and don't want/need | ||
| > to employ a transpiler themselves). This is less common nowadays for new | ||
| > libraries, but existing ones try hard to stay backwards-compatible and not | ||
| > cause applications to break. | ||
|
|
||
| ### How to build a UMD library? | ||
|
|
||
| - Set the `output.format` to `umd` in the Rslib configuration file. | ||
| - If the library need to be exported with a name, set `output.umdName` to the name of the UMD library. | ||
| - Use `output.externals` to specify the external dependencies that the UMD library depends on, `lib.autoExtension` is enabled by default for UMD. | ||
|
|
||
| ### Examples | ||
|
|
||
| The following Rslib config is an example to build a UMD library. | ||
|
|
||
| - `output.format: 'umd'`: instruct Rslib to build in UMD format. | ||
| - `output.umdName: 'RslibUmdExample'`: set the export name of the UMD library. | ||
| - `output.externals.react: 'React'`: specify the external dependency `react` could be accessed by `window.React`. | ||
| - `runtime: 'classic'`: use the classic runtime of React to support applications that using React version under 18. | ||
|
|
||
| ```ts title="rslib.config.ts" {7-12,22} | ||
| import { pluginReact } from '@rsbuild/plugin-react'; | ||
| import { defineConfig } from '@rslib/core'; | ||
|
|
||
| export default defineConfig({ | ||
| lib: [ | ||
| { | ||
| format: 'umd', | ||
| umdName: 'RslibUmdExample', | ||
| output: { | ||
| externals: { | ||
| react: 'React', | ||
| }, | ||
| distPath: { | ||
| root: './dist/umd', | ||
| }, | ||
| }, | ||
| }, | ||
| ], | ||
| plugins: [ | ||
| pluginReact({ | ||
| swcReactOptions: { | ||
| runtime: 'classic', | ||
| }, | ||
| }), | ||
| ], | ||
| }); | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Output Structure | ||
|
|
||
| ## bundle / bundleless | ||
|
|
||
| So first let's understand bundle and bundleless. | ||
|
|
||
| A bundle is a package of build artifacts, which may be a single file or multiple files based on a certain [code splitting strategy](https://esbuild.github.io/api/#splitting). | ||
|
|
||
| bundleless, on the other hand, means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of **bundleless build can also be understood as the process of code conversion of source files only**. | ||
|
|
||
| They have their own benefits. | ||
|
|
||
| - bundle can reduce the size of build artifacts and also pre-package dependencies to reduce the size of installed dependencies. Packaging libraries in advance can speed up application project builds. | ||
| - bundleless maintains the original file structure and is more conducive to debugging and tree shaking. | ||
|
|
||
| :::warning | ||
| bundleless is a single-file compilation mode, so for referencing and exporting types, you need to add the `type` keyword. For example, `import type { A } from './types'`. Please refer to [TypeScript - isolatedModules](/guide/basic/typescript#isolatedmodules) for more information. | ||
| ::: | ||
|
|
||
| You can specify whether to bundle using the [bundle](/config/lib/bundle) option, which is set to `true` by default. |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Use Typescript | ||
|
|
||
| Rslib supports TypeScript by default, allowing you to directly use `.ts` and `.tsx` files in your projects. | ||
|
|
||
| ## TypeScript Transpilation | ||
|
|
||
| Rslib uses SWC by default for transpiling TypeScript code, and it also supports switching to Babel for transpilation. | ||
|
|
||
| ### isolatedModules | ||
|
|
||
| Unlike the native TypeScript compiler, tools like SWC and Babel compile each file separately and cannot determine whether an imported name is a type or a value. Therefore, when using TypeScript in Rslib, you need to enable the [isolatedModules](https://typescriptlang.org/tsconfig/#isolatedModules) option in your `tsconfig.json` file: | ||
|
|
||
| ```json title="tsconfig.json" | ||
| { | ||
| "compilerOptions": { | ||
| "isolatedModules": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| This option can help you avoid using certain syntax that cannot be correctly compiled by SWC and Babel, such as cross-file type references. It will guide you to correct the corresponding usage: | ||
|
|
||
| ```ts | ||
| // Wrong | ||
| export { SomeType } from './types'; | ||
|
|
||
| // Correct | ||
| export type { SomeType } from './types'; | ||
| ``` | ||
|
|
||
| > See [SWC - Migrating from tsc](https://swc.rs/docs/migrating-from-tsc) for more details about the differences between SWC and tsc. | ||
|
|
||
| ## tsconfig.json Path | ||
|
|
||
| Rslib by default reads the `tsconfig.json` file from the root directory. You can use [source.tsconfigPath](https://rsbuild.dev/config/source/tsconfig-path) to configure a custom tsconfig.json file path. | ||
|
|
||
| ```ts | ||
| export default { | ||
| lib: [ | ||
| // ... | ||
| ], | ||
| source: { | ||
| tsconfigPath: './tsconfig.custom.json', | ||
| }, | ||
| }; | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| a module system used in JavaScript, particularly in server-side environments like Node.js. It was created to allow JavaScript to be used outside of the browser by providing a way to manage modules and dependencies. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| a modern module system introduced in ES2015 that allows JavaScript code to be organized into reusable, self-contained modules. ESM is now the standard for both [browser](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [Node.js](https://nodejs.org/api/esm.html) environments, replacing older module systems like [CommonJS (CJS)](https://nodejs.org/api/modules.html) and [AMD](https://requirejs.org/docs/whyamd.html). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| UMD stands for [Universal Module Definition](https://github.com/umdjs/umd), a pattern for writing JavaScript modules that can work universally across different environments, such as both the browser and Node.js. Its primary goal is to ensure compatibility with the most popular module systems, including AMD (Asynchronous Module Definition), CommonJS (CJS), and browser globals. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,25 @@ | ||
| import ESM from './components/ESM.mdx'; | ||
| import CJS from './components/CJS.mdx'; | ||
| import UMD from './components/UMD.mdx'; | ||
|
|
||
| # Glossary | ||
|
|
||
| ## ESM | ||
|
|
||
| ESM stands for ECMAScript Modules, <ESM /> | ||
|
|
||
| ## CJS | ||
|
|
||
| CJS stands for [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules), <CJS /> | ||
|
|
||
| ## UMD | ||
|
|
||
| <UMD /> | ||
|
|
||
| ## Bundleless | ||
|
|
||
| Bundleless refers to a development approach that avoids the traditional practice of bundling multiple JavaScript / TypeScript files into a single or fewer output files before serving them to the client. Instead, it aims to serve individual modules directly. | ||
|
|
||
| ## More | ||
|
|
||
| See more glossary in [Rsbuild - Glossary](https://rsbuild.dev/guide/start/glossary) and [Rspack - Glossary](https://rspack.dev/misc/glossary). |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.