From f96d5655742b4a8c64fbf3a37de90afec74bf0d2 Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 25 Aug 2023 17:00:42 +0800 Subject: [PATCH 1/4] feat(builder): add tailwind config to webpack build dependencies (#4519) --- .changeset/lazy-hotels-compete.md | 7 +++ packages/builder/builder/src/plugins/cache.ts | 59 ++++++++++++------- .../plugins/__snapshots__/cache.test.ts.snap | 12 ++++ .../builder/tests/plugins/cache.test.ts | 15 ++++- .../docs/en/guides/basic-features/css.mdx | 4 +- .../docs/zh/guides/basic-features/css.mdx | 4 +- .../guide/best-practices/use-tailwindcss.mdx | 4 +- .../guide/best-practices/use-tailwindcss.mdx | 4 +- 8 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 .changeset/lazy-hotels-compete.md diff --git a/.changeset/lazy-hotels-compete.md b/.changeset/lazy-hotels-compete.md new file mode 100644 index 000000000000..9f24ed996ccb --- /dev/null +++ b/.changeset/lazy-hotels-compete.md @@ -0,0 +1,7 @@ +--- +'@modern-js/builder': patch +--- + +feat(builder): add tailwind config to webpack build dependencies + +feat(builder): 添加 tailwind config 到 webpack build dependencies 中 diff --git a/packages/builder/builder/src/plugins/cache.ts b/packages/builder/builder/src/plugins/cache.ts index cea9e26c362a..d982a2126136 100644 --- a/packages/builder/builder/src/plugins/cache.ts +++ b/packages/builder/builder/src/plugins/cache.ts @@ -45,6 +45,44 @@ function getCacheDirectory( return join(context.cachePath, context.bundlerType); } +/** + * webpack can't detect the changes of framework config, tsconfig, tailwind config and browserslist config. + * but they will affect the compilation result, so they need to be added to buildDependencies. + */ +async function getBuildDependencies(context: Readonly) { + const { findExists } = await import('@modern-js/utils'); + const rootPackageJson = join(context.rootPath, 'package.json'); + const browserslistConfig = join(context.rootPath, '.browserslistrc'); + + const buildDependencies: Record = { + packageJson: [rootPackageJson], + }; + + if (context.configPath) { + buildDependencies.config = [context.configPath]; + } + + if (context.tsconfigPath) { + buildDependencies.tsconfig = [context.tsconfigPath]; + } + + if (await isFileExists(browserslistConfig)) { + buildDependencies.browserslistrc = [browserslistConfig]; + } + + const tailwindExts = ['ts', 'js', 'cjs', 'mjs']; + const configs = tailwindExts.map(ext => + join(context.rootPath, `tailwind.config.${ext}`), + ); + const tailwindConfig = findExists(configs); + + if (tailwindConfig) { + buildDependencies.tailwindcss = [tailwindConfig]; + } + + return buildDependencies; +} + export const builderPluginCache = (): DefaultBuilderPlugin => ({ name: 'builder-plugin-cache', @@ -59,27 +97,8 @@ export const builderPluginCache = (): DefaultBuilderPlugin => ({ const { context } = api; const cacheConfig = typeof buildCache === 'boolean' ? {} : buildCache; - const cacheDirectory = getCacheDirectory(cacheConfig, context); - const rootPackageJson = join(context.rootPath, 'package.json'); - const browserslistConfig = join(context.rootPath, '.browserslistrc'); - - /** - * webpack can't detect the changes of framework config, tsconfig and browserslist config. - * but they will affect the compilation result, so they need to be added to buildDependencies. - */ - const buildDependencies: Record = { - packageJson: [rootPackageJson], - }; - if (context.configPath) { - buildDependencies.config = [context.configPath]; - } - if (context.tsconfigPath) { - buildDependencies.tsconfig = [context.tsconfigPath]; - } - if (await isFileExists(browserslistConfig)) { - buildDependencies.browserslistrc = [browserslistConfig]; - } + const buildDependencies = await getBuildDependencies(context); await validateCache(cacheDirectory, buildDependencies); diff --git a/packages/builder/builder/tests/plugins/__snapshots__/cache.test.ts.snap b/packages/builder/builder/tests/plugins/__snapshots__/cache.test.ts.snap index 2614e4f2af39..699ecf18655a 100644 --- a/packages/builder/builder/tests/plugins/__snapshots__/cache.test.ts.snap +++ b/packages/builder/builder/tests/plugins/__snapshots__/cache.test.ts.snap @@ -7,6 +7,9 @@ exports[`plugins/cache > 'should add cache config correctly' 1`] = ` "packageJson": [ "/tests/plugins/package.json", ], + "tailwindcss": [ + "/root/tailwind.config.ts", + ], }, "cacheDirectory": "/tests/plugins/node_modules/.cache/webpack", "name": "web-development", @@ -22,6 +25,9 @@ exports[`plugins/cache > 'should custom cache directory by user' 1`] = ` "packageJson": [ "/tests/plugins/package.json", ], + "tailwindcss": [ + "/root/tailwind.config.ts", + ], }, "cacheDirectory": "/tests/plugins/node_modules/.cache/tmp", "name": "web-development", @@ -46,6 +52,9 @@ exports[`plugins/cache > 'should watch framework config change' 1`] = ` "packageJson": [ "/tests/plugins/package.json", ], + "tailwindcss": [ + "/root/tailwind.config.ts", + ], }, "cacheDirectory": "/tests/plugins/node_modules/.cache/webpack", "name": "web-development", @@ -61,6 +70,9 @@ exports[`plugins/cache > 'should watch tsconfig change' 1`] = ` "packageJson": [ "/tests/plugins/package.json", ], + "tailwindcss": [ + "/root/tailwind.config.ts", + ], "tsconfig": [ "/path/to/tsconfig.json", ], diff --git a/packages/builder/builder/tests/plugins/cache.test.ts b/packages/builder/builder/tests/plugins/cache.test.ts index 21b1cb47b5ba..4a10549d93b5 100644 --- a/packages/builder/builder/tests/plugins/cache.test.ts +++ b/packages/builder/builder/tests/plugins/cache.test.ts @@ -1,8 +1,21 @@ import { join } from 'path'; -import { expect, describe, it } from 'vitest'; +import { vi, expect, describe, it } from 'vitest'; import * as shared from '@modern-js/builder-shared'; import { builderPluginCache } from '@/plugins/cache'; +vi.mock('@modern-js/utils', async importOriginal => { + const mod = await importOriginal(); + return { + ...mod, + findExists: (files: string[]) => { + if (files.some(file => file.includes('tailwind'))) { + return '/root/tailwind.config.ts'; + } + return mod.findExists(files); + }, + }; +}); + describe('plugins/cache', () => { const cases = [ { diff --git a/packages/document/main-doc/docs/en/guides/basic-features/css.mdx b/packages/document/main-doc/docs/en/guides/basic-features/css.mdx index ffda1204f194..126804621b9b 100644 --- a/packages/document/main-doc/docs/en/guides/basic-features/css.mdx +++ b/packages/document/main-doc/docs/en/guides/basic-features/css.mdx @@ -110,9 +110,11 @@ In Modern.js, you have two ways to configure Tailwind CSS: 1. Using the `tailwind.config.{ts,js}` file, which follows the official usage of Tailwind CSS. Please refer to ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) for more details. ```ts title="tailwind.config.ts" +import type { Config } from 'tailwindcss'; + export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], -}; +} as Config; ``` :::tip diff --git a/packages/document/main-doc/docs/zh/guides/basic-features/css.mdx b/packages/document/main-doc/docs/zh/guides/basic-features/css.mdx index 4b991ed48846..e98dcc909196 100644 --- a/packages/document/main-doc/docs/zh/guides/basic-features/css.mdx +++ b/packages/document/main-doc/docs/zh/guides/basic-features/css.mdx @@ -110,9 +110,11 @@ const App = () => ( 1. 使用 `tailwind.config.{ts,js}` 文件,该用法与 Tailwind CSS 的官方用法一致,请参考 ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) 来了解更多用法。 ```ts title="tailwind.config.ts" +import type { Config } from 'tailwindcss'; + export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], -}; +} as Config; ``` :::tip diff --git a/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx b/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx index 2e81b9bacb33..43ff47aaaccb 100644 --- a/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx +++ b/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx @@ -49,9 +49,11 @@ In Module Tools, you have two ways to configure Tailwind CSS: 1. Using the `tailwind.config.{ts,js}` file, which follows the official usage of Tailwind CSS. Please refer to ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) for more details. ```ts title="tailwind.config.ts" +import type { Config } from 'tailwindcss'; + export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], -}; +} as Config; ``` :::tip diff --git a/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx b/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx index 2b0d91e56c90..f2ba99ac89bc 100644 --- a/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx +++ b/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx @@ -49,9 +49,11 @@ export default defineConfig({ 1. 使用 `tailwind.config.{ts,js}` 文件,该用法与 Tailwind CSS 的官方用法一致,请参考 ["Tailwind CSS - Configuration"](https://tailwindcss.com/docs/configuration) 来了解更多用法。 ```ts title="tailwind.config.ts" +import type { Config } from 'tailwindcss'; + export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], -}; +} as Config; ``` :::tip From 2411365a4666513bd65b71b5b17cf160a8fa89d8 Mon Sep 17 00:00:00 2001 From: 10Derozan Date: Fri, 25 Aug 2023 17:52:16 +0800 Subject: [PATCH 2/4] docs(module-tools): update doc and fix some link (#4518) --- .../docs/en/api/config/build-config.mdx | 11 +- .../docs/en/api/config/build-preset.mdx | 83 ++----------- .../docs/en/guide/advance/asset.mdx | 2 +- .../module-doc/docs/en/guide/advance/copy.md | 2 - .../en/guide/advance/external-dependency.mdx | 2 +- .../en/guide/advance/in-depth-about-build.md | 55 ++++----- .../en/guide/basic/before-getting-started.md | 2 +- .../en/guide/basic/modify-output-product.md | 114 +++++++---------- .../en/guide/basic/use-micro-generator.md | 22 ++-- .../docs/zh/api/config/build-config.mdx | 17 +-- .../docs/zh/api/config/build-preset.mdx | 81 ++---------- .../docs/zh/guide/advance/asset.mdx | 9 +- .../module-doc/docs/zh/guide/advance/copy.md | 2 - .../zh/guide/advance/external-dependency.mdx | 2 +- .../zh/guide/advance/in-depth-about-build.md | 86 +++++-------- .../zh/guide/basic/before-getting-started.md | 2 +- .../zh/guide/basic/modify-output-product.md | 115 +++++++----------- .../zh/guide/basic/use-micro-generator.md | 25 ++-- 18 files changed, 206 insertions(+), 426 deletions(-) diff --git a/packages/document/module-doc/docs/en/api/config/build-config.mdx b/packages/document/module-doc/docs/en/api/config/build-config.mdx index 04ff7df7ade4..b3e2d159a868 100644 --- a/packages/document/module-doc/docs/en/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/en/api/config/build-config.mdx @@ -7,7 +7,6 @@ sidebar_position: 1 `buildConfig` is a configuration option that describes how to compile and generate build artifacts. It contains all the configurations related to the build process. - **Type**: `object | object[]` -- **Default**: `undefined` :::tip Before start using `buildConfig`, please read the following documentation to understand its purpose: @@ -523,7 +522,7 @@ Used to set the output format of JavaScript files. The options `iife` and `umd` - **Type**: `'esm' | 'cjs' | 'iife' | 'umd'` - **Default**: `cjs` -### format: 'esm' +### format: esm `esm` stands for "ECMAScript module" and requires the runtime environment to support import and export syntax. @@ -537,7 +536,7 @@ export default defineConfig({ }); ``` -### format: 'cjs' +### format: cjs `cjs` stands for "CommonJS" and requires the runtime environment to support exports, require, and module syntax. This format is commonly used in Node.js environments. @@ -551,7 +550,7 @@ export default defineConfig({ }); ``` -### format: 'iife' +### format: iife `iife` stands for "immediately-invoked function expression" and wraps the code in a function expression to ensure that any variables in the code do not accidentally conflict with variables in the global scope. This format is commonly used in browser environments. @@ -1174,8 +1173,6 @@ export default defineConfig({ }); ``` -### Notes - Reference the [Import Plugin - Notes](plugins/official-list/plugin-import.html#Notes) ## transformLodash @@ -1187,8 +1184,6 @@ This optimization is implemented using [babel-plugin-lodash](https://www.npmjs.c - **Type**: `boolean` - **Default**: `true` -### Example - This option is enabled by default, and Module Tools will automatically redirects the code references of `lodash` to sub-paths. For example: diff --git a/packages/document/module-doc/docs/en/api/config/build-preset.mdx b/packages/document/module-doc/docs/en/api/config/build-preset.mdx index 899a82e2d46e..90fe0771b973 100644 --- a/packages/document/module-doc/docs/en/api/config/build-preset.mdx +++ b/packages/document/module-doc/docs/en/api/config/build-preset.mdx @@ -7,21 +7,8 @@ sidebar_position: 2 A build preset string or preset function. Provides out-of-the-box build configuration - **Type**: `string | Function` -- **Default**: `undefined` -## string - -The string form allows you to use the built-in presets directly - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset: 'npm-library', -}); -``` - -### `'npm-library'` +### `npm-library` Library generic schema used under class [NPM](https://www.npmjs.com/) package manager, contains `esm` and `cjs` Bundle products, and includes a type file. @@ -68,7 +55,7 @@ export const buildConfig = [ ]; ``` -### `'npm-library-with-umd'` +### `npm-library-with-umd` Used under class [NPM](https://www.npmjs.com/) package manager, and Library supports a similar pattern to [unpkg](https://unpkg.com/). Additional `umd` artifacts are provided on top of the pre-defined `npm-library`. @@ -114,7 +101,7 @@ export const buildConfig = [ ]; ``` -### `'npm-component'` +### `npm-component` A generic pattern for components (libraries) used under the class [NPM](https://www.npmjs.com/) package manager. Contains both `esm` and `cjs` Bundleless artifacts (for easy _[Tree shaking](https://developer.mozilla.org/zh-CN/docs/Glossary/Tree_shaking)_ optimization), as well as including a copy of the type file. @@ -154,7 +141,7 @@ export const buildConfig = [ ]; ``` -### `'npm-component-with-umd'` +### `npm-component-with-umd` Component (library) used under class [NPM](https://www.npmjs.com/) package manager, with support for class [unpkg](https://unpkg.com/) schema. Additional `umd` artifacts are provided on top of the pre-defined `npm-component`. @@ -198,7 +185,7 @@ export const buildConfig = [ ]; ``` -### About the ECMAScript versions supported by the presets and `{es5.... .esnext}` +### `npm-library-{es5...esnext}` When you want to use a `buildPreset` preset that supports other ECMAScript versions, you can directly add the supported versions to the `'npm-library'`, `'npm-library-with-umd'`, `'npm-component'`, `'npm-component-with-umd'` presets. @@ -212,11 +199,11 @@ export default defineConfig({ }); ``` -## Function +## string / Function -The way the function is configured, you can get the preset value from the `preset` parameter and then modify the build configuration inside to customize your build configuration. +The buildPreset not only supports basic string forms, but also function forms, which can obtain the default values we provide through the preset or extend Preset parameter and then modify them. -The following is an example of how a function can be configured to compress a build product. +Here are two examples using preset and extend Preset: ```js title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; @@ -225,63 +212,15 @@ export default defineConfig({ buildPreset({ preset }) { const { NPM_LIBRARY } = preset; return NPM_LIBRARY.map(config => { - config.minify = { - compress: { - drop_console: true, - }, + config.define = { + VERSION: '1.0.1', }; return config; }); }, }); ``` - -### Function Parameters - -The function form of `buildPreset` contains a function parameter in the form of an object. The object contains the following fields. - -- `preset` -- `extendPreset` - -#### `preset` - -Type: **Object** - -Contains the build configurations corresponding to all available build presets. Build configurations can be used by means of the strings supported by `buildPreset` or by means of underscore commands for those strings. The following are examples of the use of both approaches. - -- Use the strings supported by `buildPreset`. - -```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset({ preset }) { - return preset['npm-library']; - }, -}); -``` - -- Use the underscore naming convention for strings supported by `buildPreset`. - -```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset({ preset }) { - return preset.NPM_LIBRARY; - }, -}); -``` - -#### `extendPreset` - -Type: `Function` - -Tool function for extending a `buildPreset` to modify the build configuration corresponding to the `buildPreset`. - -> The base uses something like `{...oldBuildConfig, ...extendBuildConfig}` approach to processing. - -For example, adding the `define` configuration to the `'npm-library'` build preset. +In the `extend Preset`, lodash.merge is used for configuration merge. ```ts title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; diff --git a/packages/document/module-doc/docs/en/guide/advance/asset.mdx b/packages/document/module-doc/docs/en/guide/advance/asset.mdx index bda66a6810e1..96c487b318b5 100644 --- a/packages/document/module-doc/docs/en/guide/advance/asset.mdx +++ b/packages/document/module-doc/docs/en/guide/advance/asset.mdx @@ -19,7 +19,7 @@ For the handling of static files, the module project currently supports the foll - Set the static resource path to `. /assets`. - Files less than **10kb** will be inlined into the code. -### Example +## Example Let us look at the following example: diff --git a/packages/document/module-doc/docs/en/guide/advance/copy.md b/packages/document/module-doc/docs/en/guide/advance/copy.md index 9e23a8e26412..31052395fe25 100644 --- a/packages/document/module-doc/docs/en/guide/advance/copy.md +++ b/packages/document/module-doc/docs/en/guide/advance/copy.md @@ -13,8 +13,6 @@ We can use the Copy tool via the [`buildConfig.copy`](/en/api/config/build-confi - [`patterns`](/en/api/config/build-config#copypatterns) - [`options`](/en/api/config/build-config#copyoptions) -It is recommended to spend some time getting to know them before you start learning. - ## API Description `copy.patterns` 用于寻找复制的文件以及配置输出的路径。 diff --git a/packages/document/module-doc/docs/en/guide/advance/external-dependency.mdx b/packages/document/module-doc/docs/en/guide/advance/external-dependency.mdx index 16607e7bad74..a0fbdf0a82e6 100644 --- a/packages/document/module-doc/docs/en/guide/advance/external-dependency.mdx +++ b/packages/document/module-doc/docs/en/guide/advance/external-dependency.mdx @@ -2,7 +2,7 @@ sidebar_position: 4 --- -# How to handle third-party dependencies +# 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`. diff --git a/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md b/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md index 936566bfd57e..157a00fcd012 100644 --- a/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md +++ b/packages/document/module-doc/docs/en/guide/advance/in-depth-about-build.md @@ -12,43 +12,43 @@ If you are not familiar with `buildConfig`, please read [modify-output-product]( In this chapter we'll dive into the use of certain build configurations and understand what happens when the `modern build` command is executed. -## In-depth understanding of `buildConfig` +## buildConfig -### Bundle and Bundleless +### `bundle` / `bundleless` -So first let's understand Bundle and Bundleless. +So first let's understand bundle and bundleless. -A Bundle is a package of build products, which may be a single file or multiple files based on a certain [code splitting strategy](https://esbuild.github.io/api/#splitting). +A bundle is a package of build products, 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**. +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. +- 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 type references and exports you need to add the `type` field, e.g. `import type { A } from '. /types` +bundleless is a single file compilation mode, so for type references and exports you need to add the `type` field, e.g. `import type { A } from '. /types` ::: -In `buildConfig` you can specify whether the current build task is Bundle or Bundleless by using [`buildConfig.buildType`](/en/api/config/build-config#buildtype). +In `buildConfig` you can specify whether the current build task is bundle or bundleless by using [`buildConfig.buildType`](/en/api/config/build-config#buildtype). -### Relationship between `input` and `sourceDir` +### `input` / `sourceDir` -[`buildConfig.input`](/en/api/config/build-config#input) is used to specify the file path or directory path where the source code is read, and its default value differs between Bundle and Bundleless builds. +[`buildConfig.input`](/en/api/config/build-config#input) is used to specify the file path or directory path where the source code is read, and its default value differs between bundle and bundleless builds. - When `buildType: 'bundle'`, `input` defaults to `src/index.(j|t)sx?` - When `buildType: 'bundleless'`, `input` defaults to `['src']` :::warning -It is recommended that you do not specify multiple source file directories during a Bundleless build, as unintended results may occur. Bundleless builds with multiple source directories are currently in an unstable stage. +It is recommended that you do not specify multiple source file directories during a bundleless build, as unintended results may occur. bundleless builds with multiple source directories are currently in an unstable stage. ::: -We know from the defaults: **Bundle builds can generally specify a file path as the entry point to the build, while Bundleless builds are more expected to use directory paths to find source files**. +We know from the defaults: **bundle builds can generally specify a file path as the entry point to the build, while bundleless builds are more expected to use directory paths to find source files**. #### Object type of `input` -In addition to setting `input` to an array, you can also set it to an object during the Bundle build process. **By using the object form, we can modify the name of the file that the build artifacts outputs**. So for the following example, `. /src/index.ts` corresponds to the path of the build artifacts file as `. /dist/main.js`. +In addition to setting `input` to an array, you can also set it to an object during the bundle build process. **By using the object form, we can modify the name of the file that the build artifacts outputs**. So for the following example, `. /src/index.ts` corresponds to the path of the build artifacts file as `. /dist/main.js`. ```js title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; @@ -63,7 +63,7 @@ export default defineConfig({ }); ``` -The Bundleless build process also supports such use, but it is not recommended. +The bundleless build process also supports such use, but it is not recommended. #### `sourceDir` @@ -74,10 +74,10 @@ The Bundleless build process also supports such use, but it is not recommended. In general: -- **During the Bundleless build process, the values of `sourceDir` and `input` should be the same, and their default values are both `src`**. -- It is rarely necessary to use `sourceDir` during the Bundle build process. +- **During the bundleless build process, the values of `sourceDir` and `input` should be the same, and their default values are both `src`**. +- It is rarely necessary to use `sourceDir` during the bundle build process. -### Declaration Type Files +### dts The [`buildConfig.dts`](/en/api/config/build-config#dts) configuration is mainly used for type file generation. @@ -110,7 +110,7 @@ The **Module Tools also supports bundling of type files**, although care needs t #### Alias Conversion -During the Bundleless build process, if an alias appears in the source code, e.g. +During the bundleless build process, if an alias appears in the source code, e.g. ```js title="./src/index.ts" import utils from '@common/utils'; @@ -121,9 +121,8 @@ Normally, the type files generated with `tsc` will also contain these aliases. H - Alias conversion is possible for code of the form `import '@common/utils'` or `import utils from '@common/utils'`. - Aliasing is possible for code of the form `export { utils } from '@common/utils'`. -However, there are some cases that cannot be handled at this time. - -- Output types of the form `Promise` cannot be converted at this time. +However, there are some cases that cannot be handled at this time.Output types of the form `Promise` cannot be converted at this time. +You can discuss it [here](https://github.com/web-infra-dev/modern.js/discussions/4511) #### Some examples of the use of `dts` @@ -240,8 +239,8 @@ declare const YOUR_ADD_GLOBAL_VAR; When the `modern build` command is executed, the - Clear the output directory according to `buildConfig.outDir`. -- Compile `js/ts` source code to generate the JS build artifacts for Bundle/Bundleless. -- Generate Bundle/Bundleless type files using `tsc`. +- Compile `js/ts` source code to generate the JS build artifacts for bundle/bundleless. +- Generate bundle/bundleless type files using `tsc`. - Handle Copy tasks. ## Build errors @@ -272,7 +271,7 @@ bundle DTS failed: For `js/ts` build errors, we can tell from the error message. -- By `'bundle failed:'` to determine if the error is reported for a Bundle build or a Bundleless build? -- What is the `format` of the build process? -- What is the `target` of the build process? -- The specific error message. +- By `'bundle failed:'` to determine if the error is reported for a bundle build or a bundleless build +- What is the `format` of the build process +- What is the `target` of the build process +- The specific error message diff --git a/packages/document/module-doc/docs/en/guide/basic/before-getting-started.md b/packages/document/module-doc/docs/en/guide/basic/before-getting-started.md index 0dd20662c2d6..bef253879b0a 100644 --- a/packages/document/module-doc/docs/en/guide/basic/before-getting-started.md +++ b/packages/document/module-doc/docs/en/guide/basic/before-getting-started.md @@ -90,7 +90,7 @@ In addition to the `"main"` attribute, the `"module"` attribute is usually set. > To learn more about how webpack does this, check out this [link](https://webpack.js.org/configuration/resolve/#resolvemainfields). -### `"scripts"` +### `scripts` The `"scripts"` attribute of the `package.json` file supports a number of built-in scripts and npm-preset lifecycle events, as well as arbitrary scripts. diff --git a/packages/document/module-doc/docs/en/guide/basic/modify-output-product.md b/packages/document/module-doc/docs/en/guide/basic/modify-output-product.md index ba6c792a67de..b3eeaf5a502a 100644 --- a/packages/document/module-doc/docs/en/guide/basic/modify-output-product.md +++ b/packages/document/module-doc/docs/en/guide/basic/modify-output-product.md @@ -23,7 +23,7 @@ export default defineConfig({ **The default output files has the following characteristics**. -- will generate [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules) and [ESM](https://nodejs.org/api/esm.html#modules- ecmascript-modules). +- will generate [CommonJS](https://nodejs.org/api/modules.html#modules-commonjs-modules) and [ESM](https://nodejs.org/api/esm.html#modules-ecmascript-modules). - The code syntax is supported up to `ES6` , and more advanced syntax will be converted. - All code is bundled into one file, i.e. **bundle** processing is performed. - The output root directory is the `dist` directory under the project, and the type file output directory is `dist/types`. @@ -37,62 +37,18 @@ Then the next step is to first explain `buildPreset`. ## buildPreset -The `buildPreset` represents one or more sets of build-related configurations prepared in advance. By using the corresponding preset values of the `buildPreset`, you can eliminate the troublesome and complicated configuration work and get the expected product. +The `buildPreset` represents a prepared set or sets of build-related configurations that can be used to eliminate the trouble and complexity of configuration by using the default values corresponding to the build Preset, resulting in the expected product. -### String form of build preset +Module Tools mainly comes with two built-in build presets, including: -The value of a **build preset can be in the form of a string**, so a build preset of this form is called a preset string. +- npm-component: Used to build component libraries. +- npm-library: Used to package projects of other library types, such as tool libraries. -The Module Tools provides generic build preset strings and corresponding variants, depending on the generic scenario in which the npm package is used. All currently supported preset strings can be viewed via the [BuildPreset API](/api/config/build-preset). Here is an explanation about the relationship between **generic preset strings and variants**. +It also provides some variations, such as `npm-library-with-umd` and `npm-library-es5`, which, as their names suggest, correspond to library presets with umd output and support for es5 syntax, respectively. For more detailed configuration, you can refer to its [API](/api/config/build-preset). -Among the generic preset strings, `"npm-library"` can be used in the scenario of developing npm packages of the library type, which is suitable for most common module type projects. When `"npm-library"` is set, the output files of the project will have the following characteristics. +In addition, we can also fully customize the build configuration: -- In the `dist/lib` directory you will get code formatted as `cjs`, syntax supported up to `es6` and bundled. -- In the `dist/es` directory, you get code in the format `esm`, with syntax support up to `es6` and after bundling. -- In the `dist/types` directory, you get the type files. If it is not a TypeScript project, there is no such directory. - -The default string `"npm-library"` is a variant of the original product with a modified **code syntax support** feature and a string naming change to `"npm-library-[es5 | es2016.... . es2020 | esnext]"`. - -For example, if the output file is based on the preset string `"npm-library"` and the syntax supported by the output code is changed to `es5`, then simply changing `"npm-library"` to `"npm-library-es5"` would be sufficient. - -### Build pre-defined function forms - -**In addition to the string form, the value of a build preset can also be in the form of a function, where the specific configuration corresponding to a preset value can be printed or modified**. - -For example, to achieve the same effect as the preset string ``npm-library-es5"` using the form of a preset function, you can do the following. - -```ts title="modern.config.ts" -import { moduleTools, defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - plugins: [moduleTools()], - buildPreset({ preset }) { - return preset.NPM_LIBRARY.map(config => { - return { ... .config, target: 'es5' } - }); - }, -}); -``` - -In the above code implementation, `preset.NPM_LIBRARY` corresponds to the preset string `"npm-library"`, representing multiple build-related configurations equivalent to `"npm-library"`. - -We use the `map` method to iterate over the `NPM_LIBRARY` array, which contains multiple `buildConfig` objects. We perform a shallow copy of the original `buildConfig` object and modify the value of the `target` property in the shallow copy to be `es5`. - -If you want to know the specific contents included in `preset.NPM_LIBRARY`, you can refer to the [BuildPreset API](/api/config/build-preset). - -In addition, under the `preset` object, it not only includes `NPM_LIBRARY`, but also other similar constants. - -> NPM_LIBRARY`, you can check it with [BuildPreset API](/api/config/build-preset). The`preset`object contains not only`NPM_LIBRARY`, but also other similar constants. - -:::tip -We can not only use `preset.NPM_LIBRARY`to get the build configuration corresponding to`"npm-library"`, but also `preset['npm-library']` in this way. -::: - -So what is the `buildConfig` object here? What is the basis for the build artifacts feature mentioned before? - -Let's explain next. - -## Build configuration (object) +## buildConfig **`buildConfig` is a configuration option that describes how to compile and generate build artifacts**. What was mentioned at the beginning about "_features of build products_" are actually properties supported by `buildConfig`. The currently supported properties cover the needs of most module type projects when building products. `buildConfig` not only contains some properties that artifacts have, but also contains some features needed to build products. The following is a brief list from a classification point of view. @@ -129,36 +85,54 @@ Let's explain next. In addition to the above categories, frequently asked questions and best practices about these APIs can be found at the following links -- [What are `bundle` and `bundleless`?](/guide/advance/in-depth-about-build#bundle- and-bundleless) -- [Relationship of `input` to `sourceDir`](/guide/advance/in-depth-about-build#input- to -sourcedir-) -- [Multiple ways to generate type files in product](/guide/advance/in-depth-about-build#type-files). -- [`buildConfig.define` Different ways to use it for different scenarios.](/guide/advance/in-depth-about-build#buildconfigdefine - How to use it for different scenarios) +- [About `bundle` and `bundleless`?](/guide/advance/in-depth-about-build#bundle--bundleless) +- [About `input` and `sourceDir`](/guide/advance/in-depth-about-build#input--sourcedir) +- [About d.ts](/guide/advance/in-depth-about-build#dts). +- [How to use define](/guide/advance/in-depth-about-build#define) - [How to handle third-party dependencies?](/guide/advance/external-dependency) - [How to use copy?](/guide/advance/copy) -- How do I build umd artifacts? (/guide/advance/build-umd# sets the global variable name of the project) -- [The capabilities currently supported by static resources.](/guide/advance/asset) +- [How to use umd](/guide/advance/build-umd) +- [How to use asset](/guide/advance/asset) + +## Combining Configuration and Presets + +Once we understand `buildPreset` and `buildConfig`, we can use them together. -## When to use `buildConfig` +In a real project, we can use `buildPreset` to quickly get a set of default build configurations. If you need to customise it, you can use `buildConfig` to override and extend it. -`buildConfig` is one of the methods used to modify the product, **only `buildConfig` will take effect when configured in conjunction with `buildPreset`**. So if configured as follows. +The extension logic is as follows. + +- When `buildConfig` is an array, new configuration items are added to the original preset. ```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; +import { moduleTools, defineConfig } from '@modern-js/module-tools'; export default defineConfig({ - buildConfig: { - format: 'umd', - }, + plugins: [moduleTools()], buildPreset: 'npm-library', + buildConfig: [ + { + format: 'iife', + target: 'es2020', + outDir: '. /dist/global' + } + ] }); ``` -Then at this point you will see the following prompt. +This will generate an additional IIFE-formatted product that supports up to ES2020 syntax on top of the original preset, in the `dist/global` directory under the project. -```bash -Since both 'buildConfig' and 'buildPreset' are present, only the 'buildConfig' configuration will take effect -``` +- When `buildConfig` is an object, the configuration items in the object are overwritten in the preset. -The set or sets of build-related configurations represented by `buildPreset` are composed of `buildConfig`, **which can be used to customize output products** when the current project needs cannot be met using `buildPreset`. +```ts title="modern.config.ts" +import { moduleTools, defineConfig } from '@modern-js/module-tools'; +export default defineConfig({ + plugins: [moduleTools()], + buildPreset: 'npm-library', + buildConfig: { + sourceMap: true, + }, +}). +``` -The process of using `buildConfig` is the process of thinking about **what kind of build artifacts to get**. +This will cause a sourceMap file to be generated for each build task. diff --git a/packages/document/module-doc/docs/en/guide/basic/use-micro-generator.md b/packages/document/module-doc/docs/en/guide/basic/use-micro-generator.md index d06dfdd126cc..4a2d63ec0cfc 100644 --- a/packages/document/module-doc/docs/en/guide/basic/use-micro-generator.md +++ b/packages/document/module-doc/docs/en/guide/basic/use-micro-generator.md @@ -18,20 +18,18 @@ The microgenerator can be started via [`modern new`](/guide/basic/command-previe When we want to test some modules, we can enable the test feature. When this feature is enabled, **a `tests` directory and related files will be created in the project directory, and a new `"@modern-js/plugin-testing"` dependency will be added to package.json**. - :::tip After successfully enabling it, you will be prompted to manually add a code similar to the one below to the configuration. + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import { testingPlugin } from '@modern-js/plugin-testing'; export default defineConfig({ - plugins: [ - moduleTools(), - testingPlugin(), - ], + plugins: [moduleTools(), testingPlugin()], }); ``` + ::: ## Storybook @@ -40,17 +38,16 @@ The **Storybook feature** can be enabled when we want to debug a component or a :::tip After successfully enabling it, you will be prompted to manually add a code similar to the one below to the configuration. + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import { storybookPlugin } from '@modern-js/plugin-storybook'; export default defineConfig({ - plugins: [ - moduleTools(), - storybookPlugin(), - ], + plugins: [moduleTools(), storybookPlugin()], }); ``` + ::: For more information on how to start Storybook and how to use it, check out the following link. @@ -74,15 +71,14 @@ Also, the Storybook debugging tool will determine if the project needs to use th :::tip After successfully enabling it, you will be prompted to manually add a code similar to the one below to the configuration. + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import runtime from '@modern-js/runtime/cli'; export default defineConfig({ - plugins: [ - moduleTools(), - runtime(), - ], + plugins: [moduleTools(), runtime()], }); ``` + ::: diff --git a/packages/document/module-doc/docs/zh/api/config/build-config.mdx b/packages/document/module-doc/docs/zh/api/config/build-config.mdx index 340b2907f2e1..9b07a3b55974 100644 --- a/packages/document/module-doc/docs/zh/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/zh/api/config/build-config.mdx @@ -7,7 +7,6 @@ sidebar_position: 1 `buildConfig` 是一个用来描述如何编译、生成构建产物的配置项,它包含了构建的所有配置。 - 类型:`object | object[]` -- 默认值: `undefined` :::tip 在开始使用 `buildConfig` 之前,请先阅读以下文档来了解其作用: @@ -521,7 +520,7 @@ export default defineConfig({ - 类型:`'esm' | 'cjs' | 'iife' | 'umd'` - 默认值:`cjs` -### format: 'esm' +### format: esm esm 代表 "ECMAScript 模块",它需要运行环境支持 import 和 export 语法。 @@ -535,7 +534,7 @@ export default defineConfig({ }); ``` -### format: 'cjs' +### format: cjs cjs 代表 "CommonJS",它需要运行环境支持 exports、require 和 module 语法,通常为 Node.js 环境。 @@ -549,7 +548,7 @@ export default defineConfig({ }); ``` -### format: 'iife' +### format: iife iife 代表 "立即调用函数表达式",它将代码包裹在函数表达式中,确保代码中的任何变量不会意外地与全局范围中的变量冲突,通常在浏览器环境中运行。 @@ -563,7 +562,7 @@ export default defineConfig({ }); ``` -### format: 'umd' +### format: umd umd 代表 "Universal Module Definition",用于在不同环境(浏览器、Node.js 等)中运行。umd 格式的模块可以在多种环境下使用,既可以作为全局变量访问,也可以通过模块加载器(如 RequireJS)进行模块化加载。 @@ -1174,8 +1173,6 @@ export default defineConfig({ }); ``` -### 注意事项 - 参考[「Import 插件——注意事项」](plugins/official-list/plugin-import.html#注意事项) ## transformLodash @@ -1185,8 +1182,6 @@ export default defineConfig({ - 类型:`boolean` - 默认值:`true` -### 示例 - 该选项默认开启,Module Tools 会自动将 lodash 的代码引用指向子路径。 比如: @@ -1209,9 +1204,7 @@ const addOne = _add(1); _map([1, 2, 3], addOne); ``` -### 关闭转换 - -在个别情况下,lodash 的 import 转换可能会生成不符合预期的代码,此时你可以手动关闭这项优化: +然而有时候 lodash 的 import 转换可能会生成不符合预期的代码,此时你可以手动关闭这项优化: ```js title="modern.config.ts" export default defineConfig({ diff --git a/packages/document/module-doc/docs/zh/api/config/build-preset.mdx b/packages/document/module-doc/docs/zh/api/config/build-preset.mdx index 77c32d366785..0c8bc4c48580 100644 --- a/packages/document/module-doc/docs/zh/api/config/build-preset.mdx +++ b/packages/document/module-doc/docs/zh/api/config/build-preset.mdx @@ -9,19 +9,8 @@ sidebar_position: 2 - 类型:`string | Function` - 默认值: `undefined` -## string -字符串的形式可以让你直接使用内置的预设。 - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset: 'npm-library', -}); -``` - -### `'npm-library'` +## `npm-library` 在类 [NPM](https://www.npmjs.com/) 包管理器下使用的 Library 通用模式,包含 `esm` 和 `cjs` 两种 Bundle 产物,并且包含一份类型文件。 @@ -68,7 +57,7 @@ export const buildConfig = [ ]; ``` -### `'npm-library-with-umd'` +## `npm-library-with-umd` 在类 [NPM](https://www.npmjs.com/) 包管理器下使用,并且 Library 支持类似 [unpkg](https://unpkg.com/) 的模式。在预设 `'npm-library'` 的基础上,额外提供 `umd` 产物。 @@ -114,7 +103,7 @@ export const buildConfig = [ ]; ``` -### `'npm-component'` +## `npm-component` 在类 [NPM](https://www.npmjs.com/) 包管理器下使用的 组件(库)通用模式。包含 `esm` 和 `cjs` 两种 Bundleless 产物(便于 _[Tree shaking](https://developer.mozilla.org/zh-CN/docs/Glossary/Tree_shaking)_ 优化),以及包含一份类型文件。 @@ -154,7 +143,7 @@ export const buildConfig = [ ]; ``` -### `'npm-component-with-umd'` +## `npm-component-with-umd` 在类 [NPM](https://www.npmjs.com/) 包管理器下使用的组件(库),同时支持类 [unpkg](https://unpkg.com/) 的模式。 在预设 `'npm-component'` 的基础上,额外提供 `umd` 产物。 @@ -198,7 +187,7 @@ export const buildConfig = [ ]; ``` -### 关于预设值支持的 ECMAScript 版本以及 `{es5...esnext}` +## `npm-library-{es5...esnext}` 当想要使用支持其他 ECMAScript 版本的 `buildPreset` 预设的时候,可以直接在 `'npm-library'`、`'npm-library-with-umd'`、`'npm-component'`、`'npm-component-with-umd'` 这些预设值后面增加想要支持的版本。 @@ -212,10 +201,11 @@ export default defineConfig({ }); ``` -## Function +## string / Function -函数的配置方式,可以通过 `preset` 参数获取到预设值,然后对里面的构建配置进行修改来自定义你的构建配置。 -以下是一个函数的配置方式的例子,它配置了压缩构建产物的功能: +buildPreset 除了支持基本的字符串形式,还支持函数形式,可以通过 `preset` 或者 `extendPreset` 参数获取我们提供的预设值,然后进行修改。 + +以下是两个分别使用 `preset` 和 `extendPreset` 的例子: ```js title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; @@ -224,10 +214,8 @@ export default defineConfig({ buildPreset({ preset }) { const { NPM_LIBRARY } = preset; return NPM_LIBRARY.map(config => { - config.minify = { - compress: { - drop_console: true, - }, + config.define = { + VERSION: '1.0.1', }; return config; }); @@ -235,52 +223,7 @@ export default defineConfig({ }); ``` -### 函数参数 - -`buildPreset` 的函数形式包含了一个对象形式的函数参数。该对象包含以下字段: - -* `preset` -* `extendPreset` - -#### `preset` - -类型:**Object** - -包含了所有可用的构建预设对应的构建配置。可以通过 `buildPreset` 所支持的字符串来使用构建配置,也可以使用这些字符串的下划线命令的方式。下面是两种方式的使用示例: - -- 使用 `buildPreset` 所支持的字符串。 - -```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset({ preset }) { - return preset['npm-library']; - }, -}); -``` - -- 使用 `buildPreset` 所支持的字符串的下划线命名方式。 - -```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildPreset({ preset }) { - return preset.NPM_LIBRARY; - }, -}); -``` - -#### `extendPreset` - -类型:`Function` - -用于扩展某个 `buildPreset` 的工具函数,可以修改 `buildPreset` 对应的构建配置。 - -> 底层使用类似 `{...oldBuildConfig, ...extendBuildConfig}` 方式进行处理。 - -例如在 `'npm-library'` 构建预设的基础上增加 `define` 配置: +`extendPreset` 里会使用 lodash.merge 进行配置合并 ```ts title="modern.config.ts" import { defineConfig } from '@modern-js/module-tools'; diff --git a/packages/document/module-doc/docs/zh/guide/advance/asset.mdx b/packages/document/module-doc/docs/zh/guide/advance/asset.mdx index e42f4d4cda78..b8637db9673c 100644 --- a/packages/document/module-doc/docs/zh/guide/advance/asset.mdx +++ b/packages/document/module-doc/docs/zh/guide/advance/asset.mdx @@ -2,7 +2,7 @@ sidebar_position: 7 --- -# 处理静态资源文件 +# 处理静态资源 模块工程会对代码中使用的静态资源进行处理。如果需要配置,则可以使用 [`buildConfig.asset`](/api/config/build-config#asset) API。 @@ -16,10 +16,10 @@ sidebar_position: 7 对于静态文件的处理,模块工程目前默认支持的功能有: -- 设置静态资源路径为 `./assets`。 +- 输出静态资源至 `./assets`。 - 对于不超过 **10kb** 的文件会内联到代码中。 -### 示例 +## 示例 让我们看下面的例子: @@ -27,7 +27,6 @@ sidebar_position: 7 ```ts title="./src/asset.ts" import img from './bg.png'; -console.log(img); ``` - 如果 `bg.png` 的大小小于 10 kb,则此时产物目录结构和产物内容为: @@ -39,7 +38,6 @@ console.log(img); ```js title="./dist/asset.js" var img_default = 'data:image/png;base64,'; -console.info(img_default); ``` - 如果 `bg.png` 的大小大于 10 kb,则此时产物目录结构和产物内容为: @@ -53,7 +51,6 @@ console.info(img_default); ```js title="./dist/asset.js" import img from './assets/bg.13e2aba2.png'; -console.info(img); ``` 当你想要修改默认行为的时候,可以使用以下 API: diff --git a/packages/document/module-doc/docs/zh/guide/advance/copy.md b/packages/document/module-doc/docs/zh/guide/advance/copy.md index 294d11d4b0c8..b3c8c2fa3eb0 100644 --- a/packages/document/module-doc/docs/zh/guide/advance/copy.md +++ b/packages/document/module-doc/docs/zh/guide/advance/copy.md @@ -13,8 +13,6 @@ sidebar_position: 3 - [`patterns`](/api/config/build-config#copypatterns) - [`options`](/api/config/build-config#copyoptions) -在开始学习之前可以先花一些时间了解它们。 - ## API 详解 `copy.patterns` 用于寻找复制的文件以及配置输出的路径。 diff --git a/packages/document/module-doc/docs/zh/guide/advance/external-dependency.mdx b/packages/document/module-doc/docs/zh/guide/advance/external-dependency.mdx index 933a8cd29887..003f62ffa056 100644 --- a/packages/document/module-doc/docs/zh/guide/advance/external-dependency.mdx +++ b/packages/document/module-doc/docs/zh/guide/advance/external-dependency.mdx @@ -2,7 +2,7 @@ sidebar_position: 4 --- -# 如何处理第三方依赖 +# 处理三方依赖 一般来说,项目所需要的第三方依赖可以通过包管理器的 `install` 命令安装,在安装第三方依赖成功后,这些第三方依赖一般会出现在项目 `package.json` 的 `dependencies` 和 `devDependencies` 下。 diff --git a/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md b/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md index c2de23bc0ba5..30e4b643bada 100644 --- a/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md +++ b/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md @@ -10,62 +10,41 @@ sidebar_position: 1 如果你还不了解 `buildConfig` 的作用,请先阅读 [修改输出产物](/guide/basic/modify-output-product)。 ::: -而在本章里我们将要深入理解某些构建配置的使用以及了解执行 `modern build` 命令的时候发生了什么。 +而在本章里我们将要深入理解某些构建配置的作用以及了解执行 `modern build` 命令的时候发生了什么。 -## 深入理解 `buildConfig` +## buildConfig -### Bundle 和 Bundleless +### `bundle` / `bundleless` -那么首先我们来了解一下 Bundle 和 Bundleless。 +那么首先我们来了解一下 bundle 和 bundleless。 -所谓 Bundle 是指对构建产物进行打包,构建产物可能是一个文件,也有可能是基于一定的[代码拆分策略](https://esbuild.github.io/api/#splitting)得到的多个文件。 +所谓 bundle 是指对构建产物进行打包,构建产物可能是一个文件,也有可能是基于一定的[代码拆分策略](https://esbuild.github.io/api/#splitting)得到的多个文件。 -而 Bundleless 则是指对每个源文件单独进行编译构建,但是并不将它们打包在一起。每一个产物文件都可以找到与之相对应的源码文件。**Bundleless 构建的过程,也可以理解为仅对源文件进行代码转换的过程**。 +而 bundleless 则是指对每个源文件单独进行编译构建,但是并不将它们打包在一起。每一个产物文件都可以找到与之相对应的源码文件。**bundleless 构建的过程,也可以理解为仅对源文件进行代码转换的过程**。 它们有各自的好处: -- Bundle 可以减少构建产物的体积,也可以对依赖预打包,减小安装依赖的体积。提前对库进行打包,可以加快应用项目构建的速度。 -- Bundleless 则是可以保持原有的文件结构,更有利于调试和 tree shaking。 +- bundle 可以减少构建产物的体积,也可以对依赖预打包,减小安装依赖的体积。提前对库进行打包,可以加快应用项目构建的速度。 +- bundleless 则是可以保持原有的文件结构,更有利于调试和 tree shaking。 :::warning -Bundleless 是单文件编译模式,因此对于类型的引用和导出你需要加上 `type` 字段, 例如 `import type { A } from './types` +bundleless 是单文件编译模式,因此对于类型的引用和导出你需要加上 `type` 字段, 例如 `import type { A } from './types` ::: -在 `buildConfig` 中可以通过 [`buildConfig.buildType`](/api/config/build-config#buildtype) 来指定当前构建任务是 Bundle 还是 Bundleless。 +在 `buildConfig` 中可以通过 [`buildConfig.buildType`](/api/config/build-config#buildtype) 来指定当前构建任务是 bundle 还是 bundleless。 -### `input` 与 `sourceDir` 的关系 +### `input` / `sourceDir` -[`buildConfig.input`](/api/config/build-config#input) 用于指定读取源码的文件路径或者目录路径,其默认值在 Bundle 和 Bundleless 构建过程中有所不同: +[`buildConfig.input`](/api/config/build-config#input) 用于指定读取源码的文件路径或者目录路径,其默认值在 bundle 和 bundleless 构建过程中有所不同: - 当 `buildType: 'bundle'` 的时候,`input` 默认值为 `src/index.(j|t)sx?` - 当 `buildType: 'bundleless'` 的时候,`input` 默认值为 `['src']` :::warning -建议不要在 Bundleless 构建过程中指定多个源码文件目录,这可能会导致产物里的相对路径不正确。 +建议不要在 bundleless 构建过程中指定多个源码文件目录,这可能会导致产物里的相对路径不正确。 ::: -从默认值上我们可以知道:**Bundle 构建一般可以指定文件路径作为构建的入口,而 Bundleless 构建则更期望使用目录路径寻找源文件**。 - -#### `input` 的对象模式 - -在 Bundle 构建过程中,除了将 `input` 设置为一个数组,也可以将它设置为一个对象。**通过使用对象的形式,我们可以修改构建产物输出的文件名称**。那么对于下面的例子,`./src/index.ts` 对应的构建产物文件路径为 `./dist/main.js`。 - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - buildConfig: { - input: { - main: ['./src/index.ts'], - }, - outDir: './dist', - }, -}); -``` - -而在 Bundleless 构建过程中,虽然同样支持这样的使用方式,但是并不推荐。 - -#### `sourceDir` +从默认值上我们可以知道:**bundle 构建一般可以指定文件路径作为构建的入口,而 bundleless 构建则更期望使用目录路径寻找源文件**。 [`sourceDir`](/api/config/build-config#sourcedir) 用于指定源码目录,它主要与以下两个内容有关系: @@ -74,10 +53,10 @@ export default defineConfig({ 一般来说: -- **在 Bundleless 构建过程中,`sourceDir` 与 `input` 的值要保持一致,它们的默认值都是 `src`**。 -- 在 Bundle 构建过程中,无需使用 `sourceDir`。 +- **在 bundleless 构建过程中,`sourceDir` 与 `input` 的值要保持一致,它们的默认值都是 `src`**。 +- 在 bundle 构建过程中,无需使用 `sourceDir`。 -### 类型文件 +### dts [`buildConfig.dts`](/api/config/build-config#dts) 配置主要用于类型文件的生成。 @@ -110,7 +89,7 @@ export default defineConfig({ #### 别名转换 -在 Bundleless 构建过程中,如果源代码中出现了别名,例如: +在 bundleless 构建过程中,如果源代码中出现了别名,例如: ```js title="./src/index.ts" import utils from '@common/utils'; @@ -121,19 +100,16 @@ import utils from '@common/utils'; - 对于类似 `import '@common/utils'` 或者 `import utils from '@common/utils'` 这样形式的代码可以进行别名转换。 - 对于类似 `export { utils } from '@common/utils'` 这样形式的代码可以进行别名转换。 -然而也存在一些情况,目前还无法处理: - -- 对于类似 `Promise` 这样形式的输出类型目前无法进行转换。 +然而也存在一些情况,目前还无法处理,例如 `Promise` 这样形式的输出类型目前无法进行转换。 +对于这种情况的解决办法,可以参与[讨论](https://github.com/web-infra-dev/modern.js/discussions/4511)。 -#### 一些 `dts` 的使用示例 - -一般使用方式: +#### 一些示例 ```js import { defineConfig } from '@modern-js/module-tools'; export default defineConfig({ - // 此时打包的类型文件输出路径为 `./dist/types` + // 此时打包的类型文件输出路径为 `./dist/types`,并且将会读取项目下的 other-tsconfig.json 文件 buildConfig: { buildType: 'bundle', dts: { @@ -145,8 +121,6 @@ export default defineConfig({ }); ``` -使用 `dts.only` 的情况: - ```js import { defineConfig } from '@modern-js/module-tools'; @@ -169,7 +143,7 @@ export default defineConfig({ }); ``` -### `buildConfig.define` 不同场景的使用方式 +### `define` [`buildConfig.define`](/api/config/build-config#define) 功能有些类似 [`webpack.DefinePlugin`](https://webpack.js.org/plugins/define-plugin/)。这里介绍几个使用场景: @@ -240,9 +214,9 @@ declare const YOUR_ADD_GLOBAL_VAR; 当执行 `modern build` 命令的时候,会发生 - 根据 `buildConfig.outDir` 清理产物目录。 -- 编译 `js/ts` 源代码生成 Bundle/Bundleless 的 JS 构建产物。 -- 使用 `tsc` 生成 Bundle/Bundleless 的类型文件。 -- 处理 Copy 任务。 +- 编译 `js/ts` 源代码生成 bundle / bundleless 的 JS 构建产物。 +- 使用 `tsc` 生成 bundle / bundleless 的类型文件。 +- 处理 `copy` 任务。 ## 构建报错 @@ -272,7 +246,7 @@ bundle DTS failed: 对于 `js/ts` 构建错误,我们可以从报错信息中知道: -- 通过 `'bundle failed:'` 来判断报错的是 Bundle 构建还是 Bundleless 构建? -- 构建过程的 `format` 是什么? -- 构建过程的 `target` 是什么? -- 具体的报错信息。 +- 报错的 `buildType` +- 报错的 `format` +- 报错的 `target` +- 其他具体报错信息 diff --git a/packages/document/module-doc/docs/zh/guide/basic/before-getting-started.md b/packages/document/module-doc/docs/zh/guide/basic/before-getting-started.md index f838c9d35fca..b22ee5250275 100644 --- a/packages/document/module-doc/docs/zh/guide/basic/before-getting-started.md +++ b/packages/document/module-doc/docs/zh/guide/basic/before-getting-started.md @@ -90,7 +90,7 @@ npm Registry 是一个 [npm 包存储的地方](https://docs.npmjs.com/about-the > 想要了解关于 webpack 如何做这件事,可以查看这个[链接](https://webpack.js.org/configuration/resolve/#resolvemainfields)。 -### `"scripts"` +### "scripts" `package.json` 文件的 `"scripts"` 属性支持一些内置的脚本和 npm 预设的生命周期事件,以及任意的脚本。 diff --git a/packages/document/module-doc/docs/zh/guide/basic/modify-output-product.md b/packages/document/module-doc/docs/zh/guide/basic/modify-output-product.md index 16332cf2db99..638f5ad1690e 100644 --- a/packages/document/module-doc/docs/zh/guide/basic/modify-output-product.md +++ b/packages/document/module-doc/docs/zh/guide/basic/modify-output-product.md @@ -8,7 +8,7 @@ sidebar_position: 3 当你在初始化的项目里使用 `modern build` 命令的时候,Module Tools 会根据当前配置内容,生成相应的构建产物。 -默认的配置内容如下: +模板创建的默认配置内容如下: ```ts title="modern.config.ts" import { moduleTools, defineConfig } from '@modern-js/module-tools'; @@ -39,58 +39,17 @@ export default defineConfig({ `buildPreset` 代表着提前准备好的一组或者多组构建相关的配置,只需要使用 `buildPreset` 对应的预设值,就可以省去麻烦且复杂的配置工作,得到符合预期的产物。 -### 构建预设的字符串形式 +Module Tools 主要内置了两套构建预设,包括: -**构建预设的值可以是字符串形式**,因此这样形式的构建预设叫做预设字符串。 +- `npm-component`: 用于构建组件库。 +- `npm-library`: 用于打包其他库类型的项目,如工具库。 -模块工程解决方案根据 npm 包使用的通用场景,提供了通用的构建预设字符串以及相应的变体。目前支持的所有预设字符串可以通过 [BuildPreset API](/api/config/build-preset) 查看。这里讲解一下关于**通用的预设字符串与变体之间的关系**。 +同时,还提供一些变体,例如 `npm-library-with-umd` 和 `npm-library-es5`,顾名思义,分别对应带有 umd 产物和支持到 es5 语法的库预设。 +详细配置可以查看其[API](/api/config/build-preset)。 -在通用的预设字符串中,`"npm-library"` 可以用于在开发库类型的 npm 包的场景下使用,它适合大多数普通的模块类型项目。当设置 `"npm-library"` 的时候,项目的输出产物会有以下特点: +除此之外,我们也可以完全自定义构建配置: -- 在 `dist/lib` 目录下会得到代码格式为 `cjs`、语法支持到 `es6` 且经过打包处理后的产物。 -- 在 `dist/es` 目录下会得到代码格式为 `esm`、语法支持为 `es6` 且经过打包处理后的产物。 -- 在 `dist/types` 目录下会得到类型文件。如果不是 TypeScript 项目,则没有该目录。 - -而预设字符串 `"npm-library"` 对应的变体则是在原本产物的基础上修改了**代码语法支持**这一特点,同时在字符串命名上也变为了 `"npm-library-[es5 | es2016...es2020 | esnext]"` 这样的形式。 - -例如,如果在预设字符串 `"npm-library"` 对应的输出产物基础上,让产物代码支持的语法变为 `es5` 的话,那么只需要将 `"npm-library"` 改变为 `"npm-library-es5"` 就可以了。 - -### 构建预设的函数形式 - -**除了字符串形式以外,构建预设的值也可以是函数形式,在函数中可以打印或者修改某个预设值对应的具体配置**。 - -例如,如果使用预设函数的形式达到预设字符串 `"npm-library-es5"` 同样的效果,可以按照如下的方式: - -```ts title="modern.config.ts" -import { moduleTools, defineConfig } from '@modern-js/module-tools'; - -export default defineConfig({ - plugins: [moduleTools()], - buildPreset({ preset }) { - return preset.NPM_LIBRARY.map(config => { - return { ...config, target: 'es5' }; - }); - }, -}); -``` - -在上面的代码实现中,`preset.NPM_LIBRARY` 与预设字符串 `"npm-library"` 是相对应的,它代表与 `"npm-library"` 等价的多个构建相关的配置。 - -我们通过 `map` 方法遍历了 `NPM_LIBRARY` 这个数组,在这个数组中包含了多个 `buildConfig` 对象。我们将原本的 `buildConfig` 对象进行了浅拷贝,并修改了浅拷贝后 `target` 的值,将它指定为 `es5`。 - -如果你想了解 `preset.NPM_LIBRARY` 具体包含的内容,可以通过 [BuildPreset API](/api/config/build-preset) 查看。 - -此外,在 `preset` 对象下,不仅包含了 `NPM_LIBRARY`,也包含了其他类似的常量。 - -:::tip -我们不仅可以使用 `preset.NPM_LIBRARY` 来获取 `"npm-library"` 对应的构建配置,也可以使用 `preset['npm-library']` 这样的方式。 -::: - -那么这里的 `buildConfig` 对象是什么呢?之前提到的构建产物特点又是根据什么呢? - -接下来我们解释一下。 - -## 构建配置(对象) +## 构建配置 **`buildConfig` 是一个用来描述如何编译、生成构建产物的配置项**。在最开始提到的关于“_构建产物的特点_”,其实都是 `buildConfig` 所支持的属性。目前所支持的属性覆盖了大部分模块类型项目在构建产物时的需求,`buildConfig` 不仅包含一些产物所具备的属性,也包含了构建产物所需要的一些特性功能。接下来从分类的角度简单罗列一下: @@ -127,36 +86,54 @@ export default defineConfig({ 除了以上分类以外,关于这些 API 的常见问题和最佳实践可以通过下面的链接来了解: -- [什么是 `bundle` 和 `bundleless`?](/guide/advance/in-depth-about-build#bundle-和-bundleless) -- [`input` 与 `sourceDir` 的关系](/guide/advance/in-depth-about-build#input-与-sourcedir-的关系)。 -- [产物中类型文件的多种生成方式](/guide/advance/in-depth-about-build#类型文件)。 -- [`buildConfig.define` 不同场景的使用方式。](/guide/advance/in-depth-about-build#buildconfigdefine-不同场景的使用方式) -- [如何处理第三方依赖?](/guide/advance/external-dependency) -- [如何使用拷贝?](/guide/advance/copy) -- [如何构建 umd 产物?](/guide/advance/build-umd#设置项目的全局变量名称) -- [静态资源目前所支持的能力。](/guide/advance/asset) +- [关于 `bundle` 和 `bundleless`](/guide/advance/in-depth-about-build#bundle--bundleless) +- [关于 `input` 和 `sourceDir`](/guide/advance/in-depth-about-build#input--sourcedir)。 +- [关于类型描述文件](/guide/advance/in-depth-about-build#dts)。 +- [如何使用 define](/guide/advance/in-depth-about-build#define) +- [如何处理第三方依赖](/guide/advance/external-dependency) +- [如何使用拷贝](/guide/advance/copy) +- [如何构建 umd 产物](/guide/advance/build-umd) +- [如何使用静态资源](/guide/advance/asset) + +## 结合配置与预设 + +了解 `buildPreset` 和 `buildConfig` 之后,我们可以将二者进行结合使用。 -## 什么时候使用 `buildConfig` +在实际项目中,我们可以先使用 `buildPreset` 来快速获取一套默认构建配置。如果需要自定义,可以使用 `buildConfig` 进行覆盖和扩展。 -`buildConfig` 是用于修改产物的方式之一,**当与 `buildPreset` 配置同时存在的时候,只有 `buildConfig` 才会生效**。因此如果按照如下方式配置: +扩展的逻辑如下: + +- 当 `buildConfig` 是数组时,会在原来的预设基础上添加新的配置项。 ```ts title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; +import { moduleTools, defineConfig } from '@modern-js/module-tools'; export default defineConfig({ - buildConfig: { - format: 'umd', - }, + plugins: [moduleTools()], buildPreset: 'npm-library', + buildConfig: [ + { + format: 'iife', + target: 'es2020', + outDir: './dist/global' + } + ] }); ``` -那么此时就会看到如下提示: +这会在原本预设的基础上,额外生成一份 IIFE 格式、支持到 ES2020 语法的产物,输出目录为项目下的 `dist/global` 目录。 -```bash -因为同时出现 'buildConfig' 和 'buildPreset' 配置,因此仅 'buildConfig' 配置生效 -``` +- 当 `buildConfig` 是对象时,会将对象中的配置项覆盖到预设中。 -`buildPreset` 代表的一组或者多组构建相关的配置都是由 `buildConfig` 组成,**当使用 `buildPreset` 无法满足当前项目需求的时候,就可以使用 `buildConfig` 来自定义输出产物**。 +```ts title="modern.config.ts" +import { moduleTools, defineConfig } from '@modern-js/module-tools'; +export default defineConfig({ + plugins: [moduleTools()], + buildPreset: 'npm-library', + buildConfig: { + sourceMap: true, + } +}); +``` -在使用 `buildConfig` 的过程,就是对**获得怎样的构建产物**的思考过程。 +这会使得每一项构建任务都会生成 sourceMap 文件。 diff --git a/packages/document/module-doc/docs/zh/guide/basic/use-micro-generator.md b/packages/document/module-doc/docs/zh/guide/basic/use-micro-generator.md index 58854dcface8..44d17849d8a2 100644 --- a/packages/document/module-doc/docs/zh/guide/basic/use-micro-generator.md +++ b/packages/document/module-doc/docs/zh/guide/basic/use-micro-generator.md @@ -7,7 +7,7 @@ sidebar_position: 4 模块工程解决方案提供了微生成器工具,它可以为当前项目: - 新增目录和文件 -- 修改 `package.json` 文件内容 +- 修改 `package.json` - 执行命令 因此通过这些能力,**微生成器可以为项目开启额外的特性功能**。 @@ -20,17 +20,16 @@ sidebar_position: 4 :::tip 在成功开启后,会提示需要手动在配置中增加如下类似的代码。 + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import { testingPlugin } from '@modern-js/plugin-testing'; export default defineConfig({ - plugins: [ - moduleTools(), - testingPlugin(), - ], + plugins: [moduleTools(), testingPlugin()], }); ``` + ::: ## Storybook 调试 @@ -39,17 +38,16 @@ export default defineConfig({ :::tip 在成功开启后,会提示需要手动在配置中增加如下类似的代码。 + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import { storybookPlugin } from '@modern-js/plugin-storybook'; export default defineConfig({ - plugins: [ - moduleTools(), - storybookPlugin(), - ], + plugins: [moduleTools(), storybookPlugin()], }); ``` + ::: 关于如何启动 Storybook 以及如何使用 Storybook,可以查看下面的链接: @@ -63,7 +61,7 @@ export default defineConfig({ 如果你想要在项目使用 [Tailwind CSS](https://tailwindcss.com/),可以参考 [「使用 Tailwind CSS」](https://modernjs.dev/module-tools/guide/best-practices/components.html#tailwind-css)。 -## 启动 Modern.js Runtime API +## Modern.js Runtime API 支持 **Modern.js 提供了 [Runtime API](https://modernjs.dev/configure/app/runtime/intro) 能力,这些 API 只能在 Modern.js 的应用项目环境中使用**。如果你需要开发一个 Modern.js 应用环境中使用的组件,那么你可以开启该特性,微生成器会增加 `"@modern-js/runtime"`依赖。 @@ -71,15 +69,14 @@ export default defineConfig({ :::tip 在成功开启后,会提示需要手动在配置中增加如下类似的代码。 + ```ts import { moduleTools, defineConfig } from '@modern-js/module-tools'; import runtime from '@modern-js/runtime/cli'; export default defineConfig({ - plugins: [ - moduleTools(), - runtime(), - ], + plugins: [moduleTools(), runtime()], }); ``` + ::: From 0d915fa52aee94fc9e548834e78edfd346b1e376 Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 25 Aug 2023 17:54:54 +0800 Subject: [PATCH 3/4] docs(tailwindcss): mark designSystem as deprecated (#4521) --- .../en/configure/app/source/design-system.mdx | 1175 ----------------- .../en/configure/app/tools/tailwindcss.mdx | 33 +- .../zh/configure/app/source/design-system.mdx | 1174 ---------------- .../zh/configure/app/tools/tailwindcss.mdx | 33 +- .../docs/en/api/config/build-config.mdx | 4 +- .../docs/en/api/config/design-system.md | 1166 ---------------- .../docs/en/guide/advance/theme-config.mdx | 60 - .../guide/best-practices/use-tailwindcss.mdx | 29 + .../docs/en/plugins/guide/setup-function.mdx | 1 - .../docs/zh/api/config/build-config.mdx | 4 +- .../docs/zh/api/config/design-system.md | 1166 ---------------- .../docs/zh/guide/advance/theme-config.mdx | 64 - .../guide/best-practices/use-tailwindcss.mdx | 29 + .../docs/zh/plugins/guide/setup-function.mdx | 1 - .../templates/docs/zh/guide/install.mdx | 1 - .../app-tools/src/types/config/source.ts | 6 +- .../src/types/legacyConfig/source.ts | 5 +- .../module-tools/src/types/config/index.ts | 4 + .../src/types/legacyConfig/source.ts | 5 +- 19 files changed, 136 insertions(+), 4824 deletions(-) delete mode 100644 packages/document/main-doc/docs/en/configure/app/source/design-system.mdx delete mode 100644 packages/document/main-doc/docs/zh/configure/app/source/design-system.mdx delete mode 100644 packages/document/module-doc/docs/en/api/config/design-system.md delete mode 100644 packages/document/module-doc/docs/en/guide/advance/theme-config.mdx delete mode 100644 packages/document/module-doc/docs/zh/api/config/design-system.md delete mode 100644 packages/document/module-doc/docs/zh/guide/advance/theme-config.mdx diff --git a/packages/document/main-doc/docs/en/configure/app/source/design-system.mdx b/packages/document/main-doc/docs/en/configure/app/source/design-system.mdx deleted file mode 100644 index 4c135a7bcf23..000000000000 --- a/packages/document/main-doc/docs/en/configure/app/source/design-system.mdx +++ /dev/null @@ -1,1175 +0,0 @@ ---- -sidebar_label: designSystem ---- - -# source.designSystem - -- **Type:** `Object` -- **Default:** See configuration details below. - -:::caution -Tailwind CSS feature needs to be enabled first by running `pnpm run new`. - -::: - -
- DesignSystem Configuration Details - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, - colors: { - transparent: 'transparent', - current: 'currentColor', - - black: '#000', - white: '#fff', - - gray: { - 100: '#f7fafc', - 200: '#edf2f7', - 300: '#e2e8f0', - 400: '#cbd5e0', - 500: '#a0aec0', - 600: '#718096', - 700: '#4a5568', - 800: '#2d3748', - 900: '#1a202c', - }, - red: { - 100: '#fff5f5', - 200: '#fed7d7', - 300: '#feb2b2', - 400: '#fc8181', - 500: '#f56565', - 600: '#e53e3e', - 700: '#c53030', - 800: '#9b2c2c', - 900: '#742a2a', - }, - orange: { - 100: '#fffaf0', - 200: '#feebc8', - 300: '#fbd38d', - 400: '#f6ad55', - 500: '#ed8936', - 600: '#dd6b20', - 700: '#c05621', - 800: '#9c4221', - 900: '#7b341e', - }, - yellow: { - 100: '#fffff0', - 200: '#fefcbf', - 300: '#faf089', - 400: '#f6e05e', - 500: '#ecc94b', - 600: '#d69e2e', - 700: '#b7791f', - 800: '#975a16', - 900: '#744210', - }, - green: { - 100: '#f0fff4', - 200: '#c6f6d5', - 300: '#9ae6b4', - 400: '#68d391', - 500: '#48bb78', - 600: '#38a169', - 700: '#2f855a', - 800: '#276749', - 900: '#22543d', - }, - teal: { - 100: '#e6fffa', - 200: '#b2f5ea', - 300: '#81e6d9', - 400: '#4fd1c5', - 500: '#38b2ac', - 600: '#319795', - 700: '#2c7a7b', - 800: '#285e61', - 900: '#234e52', - }, - blue: { - 100: '#ebf8ff', - 200: '#bee3f8', - 300: '#90cdf4', - 400: '#63b3ed', - 500: '#4299e1', - 600: '#3182ce', - 700: '#2b6cb0', - 800: '#2c5282', - 900: '#2a4365', - }, - indigo: { - 100: '#ebf4ff', - 200: '#c3dafe', - 300: '#a3bffa', - 400: '#7f9cf5', - 500: '#667eea', - 600: '#5a67d8', - 700: '#4c51bf', - 800: '#434190', - 900: '#3c366b', - }, - purple: { - 100: '#faf5ff', - 200: '#e9d8fd', - 300: '#d6bcfa', - 400: '#b794f4', - 500: '#9f7aea', - 600: '#805ad5', - 700: '#6b46c1', - 800: '#553c9a', - 900: '#44337a', - }, - pink: { - 100: '#fff5f7', - 200: '#fed7e2', - 300: '#fbb6ce', - 400: '#f687b3', - 500: '#ed64a6', - 600: '#d53f8c', - 700: '#b83280', - 800: '#97266d', - 900: '#702459', - }, - }, - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, - backgroundColor: theme => theme('colors'), - backgroundOpacity: theme => theme('opacity'), - backgroundPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundSize: { - auto: 'auto', - cover: 'cover', - contain: 'contain', - }, - borderColor: theme => ({ - ...theme('colors'), - default: theme('colors.gray.300', 'currentColor'), - }), - borderOpacity: theme => theme('opacity'), - borderRadius: { - none: '0', - sm: '0.125rem', - default: '0.25rem', - md: '0.375rem', - lg: '0.5rem', - full: '9999px', - }, - borderWidth: { - default: '1px', - 0: '0', - 2: '2px', - 4: '4px', - 8: '8px', - }, - boxShadow: { - xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', - sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', - default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', - inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', - outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', - none: 'none', - }, - container: {}, - cursor: { - auto: 'auto', - default: 'default', - pointer: 'pointer', - wait: 'wait', - text: 'text', - move: 'move', - 'not-allowed': 'not-allowed', - }, - divideColor: theme => theme('borderColor'), - divideOpacity: theme => theme('borderOpacity'), - divideWidth: theme => theme('borderWidth'), - fill: { - current: 'currentColor', - }, - flex: { - 1: '1 1 0%', - auto: '1 1 auto', - initial: '0 1 auto', - none: 'none', - }, - flexGrow: { - 0: '0', - default: '1', - }, - flexShrink: { - 0: '0', - default: '1', - }, - fontFamily: { - sans: [ - 'system-ui', - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - '"Noto Sans"', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - '"Noto Color Emoji"', - ], - serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], - mono: [ - 'Menlo', - 'Monaco', - 'Consolas', - '"Liberation Mono"', - '"Courier New"', - 'monospace', - ], - }, - fontSize: { - xs: '0.75rem', - sm: '0.875rem', - base: '1rem', - lg: '1.125rem', - xl: '1.25rem', - '2xl': '1.5rem', - '3xl': '1.875rem', - '4xl': '2.25rem', - '5xl': '3rem', - '6xl': '4rem', - }, - fontWeight: { - hairline: '100', - thin: '200', - light: '300', - normal: '400', - medium: '500', - semibold: '600', - bold: '700', - extrabold: '800', - black: '900', - }, - height: theme => ({ - auto: 'auto', - ...theme('spacing'), - full: '100%', - screen: '100vh', - }), - inset: { - 0: '0', - auto: 'auto', - }, - letterSpacing: { - tighter: '-0.05em', - tight: '-0.025em', - normal: '0', - wide: '0.025em', - wider: '0.05em', - widest: '0.1em', - }, - lineHeight: { - none: '1', - tight: '1.25', - snug: '1.375', - normal: '1.5', - relaxed: '1.625', - loose: '2', - 3: '.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 7: '1.75rem', - 8: '2rem', - 9: '2.25rem', - 10: '2.5rem', - }, - listStyleType: { - none: 'none', - disc: 'disc', - decimal: 'decimal', - }, - margin: (theme, { negative }) => ({ - auto: 'auto', - ...theme('spacing'), - ...negative(theme('spacing')), - }), - maxHeight: { - full: '100%', - screen: '100vh', - }, - maxWidth: (theme, { breakpoints }) => ({ - none: 'none', - xs: '20rem', - sm: '24rem', - md: '28rem', - lg: '32rem', - xl: '36rem', - '2xl': '42rem', - '3xl': '48rem', - '4xl': '56rem', - '5xl': '64rem', - '6xl': '72rem', - full: '100%', - ...breakpoints(theme('screens')), - }), - minHeight: { - 0: '0', - full: '100%', - screen: '100vh', - }, - minWidth: { - 0: '0', - full: '100%', - }, - objectPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - opacity: { - 0: '0', - 25: '0.25', - 50: '0.5', - 75: '0.75', - 100: '1', - }, - order: { - first: '-9999', - last: '9999', - none: '0', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - }, - padding: theme => theme('spacing'), - placeholderColor: theme => theme('colors'), - placeholderOpacity: theme => theme('opacity'), - space: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - }), - stroke: { - current: 'currentColor', - }, - strokeWidth: { - 0: '0', - 1: '1', - 2: '2', - }, - textColor: theme => theme('colors'), - textOpacity: theme => theme('opacity'), - width: theme => ({ - auto: 'auto', - ...theme('spacing'), - '1/2': '50%', - '1/3': '33.333333%', - '2/3': '66.666667%', - '1/4': '25%', - '2/4': '50%', - '3/4': '75%', - '1/5': '20%', - '2/5': '40%', - '3/5': '60%', - '4/5': '80%', - '1/6': '16.666667%', - '2/6': '33.333333%', - '3/6': '50%', - '4/6': '66.666667%', - '5/6': '83.333333%', - '1/12': '8.333333%', - '2/12': '16.666667%', - '3/12': '25%', - '4/12': '33.333333%', - '5/12': '41.666667%', - '6/12': '50%', - '7/12': '58.333333%', - '8/12': '66.666667%', - '9/12': '75%', - '10/12': '83.333333%', - '11/12': '91.666667%', - full: '100%', - screen: '100vw', - }), - zIndex: { - auto: 'auto', - 0: '0', - 10: '10', - 20: '20', - 30: '30', - 40: '40', - 50: '50', - }, - gap: theme => theme('spacing'), - gridTemplateColumns: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - 7: 'repeat(7, minmax(0, 1fr))', - 8: 'repeat(8, minmax(0, 1fr))', - 9: 'repeat(9, minmax(0, 1fr))', - 10: 'repeat(10, minmax(0, 1fr))', - 11: 'repeat(11, minmax(0, 1fr))', - 12: 'repeat(12, minmax(0, 1fr))', - }, - gridColumn: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - 'span-7': 'span 7 / span 7', - 'span-8': 'span 8 / span 8', - 'span-9': 'span 9 / span 9', - 'span-10': 'span 10 / span 10', - 'span-11': 'span 11 / span 11', - 'span-12': 'span 12 / span 12', - }, - gridColumnStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridColumnEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridTemplateRows: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - }, - gridRow: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - }, - gridRowStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - gridRowEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - transformOrigin: { - center: 'center', - top: 'top', - 'top-right': 'top right', - right: 'right', - 'bottom-right': 'bottom right', - bottom: 'bottom', - 'bottom-left': 'bottom left', - left: 'left', - 'top-left': 'top left', - }, - scale: { - 0: '0', - 50: '.5', - 75: '.75', - 90: '.9', - 95: '.95', - 100: '1', - 105: '1.05', - 110: '1.1', - 125: '1.25', - 150: '1.5', - }, - rotate: { - '-180': '-180deg', - '-90': '-90deg', - '-45': '-45deg', - 0: '0', - 45: '45deg', - 90: '90deg', - 180: '180deg', - }, - translate: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - '-full': '-100%', - '-1/2': '-50%', - '1/2': '50%', - full: '100%', - }), - skew: { - '-12': '-12deg', - '-6': '-6deg', - '-3': '-3deg', - 0: '0', - 3: '3deg', - 6: '6deg', - 12: '12deg', - }, - transitionProperty: { - none: 'none', - all: 'all', - default: - 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', - colors: 'background-color, border-color, color, fill, stroke', - opacity: 'opacity', - shadow: 'box-shadow', - transform: 'transform', - }, - transitionTimingFunction: { - linear: 'linear', - in: 'cubic-bezier(0.4, 0, 1, 1)', - out: 'cubic-bezier(0, 0, 0.2, 1)', - 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', - }, - transitionDuration: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, - transitionDelay: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, -}; -``` - -
- -:::tip -For more information on Tailwind CSS configuration, please refer to [here](https://tailwindcss.com/docs/configuration#theme). - -::: - -The `designSystem` is used to define the project's color palette, typographic scales, font list, breakpoints, border radius values, and more. As Modern.js uses the design approach of Tailwind Theme and also integrates Tailwind CSS internally, the usage of `designSystem` is the same as that of Tailwind CSS Theme. - -### Structure - -The `designSystem` object contains properties for `screens`, `colors`, `spacing`, and each customizable core plugin. - -#### Screens - -Use `screens` to customize the responsive breakpoints in your project: - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, -}; -``` - -The property names in the `screens` object are screen names (used as prefixes for the responsive utility variants generated by Tailwind CSS, such as `md:text-center`), and the values are the `min-width` at which the breakpoint should start. - -The default breakpoints are inspired by common device resolutions: - -```js -const designSystem = { - screens: { - sm: '640px', - // => @media (min-width: 640px) { ... } - - md: '768px', - // => @media (min-width: 768px) { ... } - - lg: '1024px', - // => @media (min-width: 1024px) { ... } - - xl: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -You can use any names you like as properties for your breakpoints in your project: - -```js -const designSystem = { - screens: { - tablet: '640px', - // => @media (min-width: 640px) { ... } - - laptop: '1024px', - // => @media (min-width: 1024px) { ... } - - desktop: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -These screen names are reflected in `utilities`, so `text-center` would now look like this: - -```css -.text-center { - text-align: center; -} - -@media (min-width: 640px) { - .tablet\:text-center { - text-align: center; - } -} - -@media (min-width: 1024px) { - .laptop\:text-center { - text-align: center; - } -} - -@media (min-width: 1280px) { - .desktop\:text-center { - text-align: center; - } -} -``` - -##### Max-width Breakpoint - -If you want to use `max-width` breakpoints instead of `min-width`, you can specify the screen as an object with a `max` property: - -```js -const designSystem = { - screens: { - xl: { max: '1279px' }, - // => @media (max-width: 1279px) { ... } - - lg: { max: '1023px' }, - // => @media (max-width: 1023px) { ... } - - md: { max: '767px' }, - // => @media (max-width: 767px) { ... } - - sm: { max: '639px' }, - // => @media (max-width: 639px) { ... } - }, -}; -``` - -If necessary, you can create breakpoints with both `min-width` and `max-width` definitions, like so: - -```js -const designSystem = { - screens: { - sm: { min: '640px', max: '767px' }, - md: { min: '768px', max: '1023px' }, - lg: { min: '1024px', max: '1279px' }, - xl: { min: '1280px' }, - }, -}; -``` - -##### Breakpoints with Multiple Ranges - -Sometimes it can be useful to apply a single breakpoint definition to multiple ranges. - -For example, suppose you have a `sidebar` and want to base the breakpoints on the width of the content area rather than the entire viewport. You can simulate this by using a smaller breakpoint style when the `sidebar` is visible and the content area is reduced: - -```js -const designSystem = { - screens: { - sm: '500px', - md: [ - // Sidebar appears at 768px, so revert to `sm:` styles between 768px - // and 868px, after which the main content area is wide enough again to - // apply the `md:` styles. - { min: '668px', max: '767px' }, - { min: '868px' }, - ], - lg: '1100px', - xl: '1400px', - }, -}; -``` - -##### Custom Media Queries - -If you need to provide fully custom media queries for your breakpoints, you can use an object with a `raw` property: - -```js -const designSystem = { - extend: { - screens: { - portrait: { raw: '(orientation: portrait)' }, - // => @media (orientation: portrait) { ... } - }, - }, -}; -``` - -##### Print Style - -The `raw` option may be especially useful if you need to apply different styles for printing. - -All you need to do is add a `print` under `designSystem.extend.screens`: - -```js -const designSystem = { - extend: { - screens: { - print: { raw: 'print' }, - // => @media print { ... } - }, - }, -}; -``` - -Then, you can use classes like `print:text-black` to specify styles that should only be applied when someone tries to print the page: - -```html -
- {/* ... */} -
-``` - -##### Dark Mode - -The `raw` option can be used to implement "dark mode" screens: - -```js -const designSystem = { - extend: { - screens: { - dark: { raw: '(prefers-color-scheme: dark)' }, - // => @media (prefers-color-scheme: dark) { ... } - }, - }, -}; -``` - -Then, you can use the `dark:` prefix to set different styles for elements in dark mode: - -```html -
- {/* ... */} -
-``` - -Please note that since these screen variants are implemented in Tailwind CSS, **it is not possible to use this method to combine breakpoints with dark mode**, e.g. `md:dark:text-gray-300` will not work. - -#### Colors - -The `colors` property allows you to customize the global color palette for your project. - -```js -const designSystem = { - colors: { - transparent: 'transparent', - black: '#000', - white: '#fff', - gray: { - 100: '#f7fafc', - // ... - 900: '#1a202c', - }, - - // ... - }, -}; -``` - -By default, these colors are inherited by the `backgroundColor`, `textColor`, and `borderColor` core plugins. - -For more information, see [Customizing Colors](https://tailwindcss.com/docs/customizing-colors). - -#### Spacing - -Use the `space` property to customize the global spacing and scale ratios for your project: - -```js -const designSystem = { - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, -}; -``` - -By default, these values are inherited by the `padding`, `margin`, `negativeMargin`, `width`, and `height` core plugins. - -For more information, see [Customizing Spacing](https://tailwindcss.com/docs/customizing-spacing). - -#### Core Plugins - -The rest of the theme section is used to configure the values available for each core plugin. - -For example, the `borderRadius` property allows you to customize the `utilities` for the generated border radius: - -```js -const designSystem = { - borderRadius: { - none: '0', - sm: '.125rem', - default: '.25rem', - lg: '.5rem', - full: '9999px', - }, -}; -``` - -**The property name determines the suffix of the generated classes, and the value determines the value of the actual CSS declaration.** The `borderRadius` configuration example above will generate the following CSS classes: - -```css -.rounded-none { - border-radius: 0; -} -.rounded-sm { - border-radius: 0.125rem; -} -.rounded { - border-radius: 0.25rem; -} -.rounded-lg { - border-radius: 0.5rem; -} -.rounded-full { - border-radius: 9999px; -} -``` - -You may notice that the `rounded` class without a suffix is created using the `default` property in the theme configuration. This is a common convention in Tailwind CSS that many (although not all) core plugins support. - -For more information on customizing specific core plugins, see the documentation for that plugin. - -### Customizing the Default Configuration - -Out of the box, your project will inherit values from the default theme configuration. If you want to customize the default theme, there are a few different options depending on your goals. - -#### Overriding Default Configuration - -To override an option in the default configuration, add the property you want to override to `designSystem`: - -```ts title="modern.config.ts" -const designSystem = { - // Replaces all of the default `opacity` values - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -This will completely replace the default property configuration, so in the example above, the default `opacity utilities` will not be generated. - -Any properties you don't provide will still inherit from the default theme, so in the example above, the default theme configuration for colors, spacing, border radius, background positions, etc. will be preserved. - -#### Extending Default Configuration - -If you want to keep the default values for a theme option but add new values, add the extension under the `designSystem.extend` property. - -For example, if you want to add an additional breakpoint but keep the existing ones, you can extend the `screens` property: - -```ts title="modern.config.ts" -const designSystem = { - extend: { - // Adds a new breakpoint in addition to the default breakpoints - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -Of course, you can override some parts of the default theme and extend other parts of the default theme in the same configuration: - -```ts title="modern.config.ts" -const designSystem = { - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, - extend: { - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -#### Referencing Other Values - -If you need to reference another value in your configuration, you can do so by providing a closure function instead of a static value. The function will receive the `theme()` function as an argument, which you can use to look up other values in the configuration using dot notation. - -For example, you can generate `fill` utilities for each color in your palette by referencing `theme('colors')` on the `fill` configuration: - -```ts title="modern.config.ts" -const designSystem = { - colors: { - // ... - }, - fill: theme => theme('colors'), -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -The `theme()` function attempts to find the value you're looking for from the fully merged configuration object, so it can reference your own custom settings as well as default theme values. It also works recursively, so as long as there's a static value at the end of the chain, it can resolve the value you're looking for. - -**Referencing Default Configuration** - -If you want to reference a value from the default configuration for any reason, you can import it from `tailwindcss/defaultTheme`. A useful example is if you want to add a font from the fonts provided by the default configuration: - -```ts title="modern.config.ts" -const defaultTheme = require('tailwindcss/defaultTheme'); - -const designSystem = { - extend: { - fontFamily: { - sans: ['Lato', ...defaultTheme.fontFamily.sans], - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -#### Disabling Entire Core Plugins - -If you don't want to generate any classes for a particular core plugin, it's best to set that plugin to `false` in the `corePlugins` configuration rather than providing an empty object for that property in the configuration: - -```js -// Don't assign an empty object in your theme configuration - -const designSystem = { - opacity: {}, -}; - -// Do disable the plugin in your corePlugins configuration -const designSyttem = { - corePlugins: { - opacity: false, - }, -}; -``` - -The end result is the same, but since many core plugins don't expose any configuration, they can only be disabled using `corePlugins`, so it's best to be consistent. - -#### Adding Your Own Keys - -In many cases, adding your own properties to the configuration object can be useful. - -One example of this is adding a new property for reuse between multiple core plugins. For example, you could extract a `positions` object that both the `backgroundPosition` and `objectPosition` plugins could reference: - -```js -const designSystem = { - positions: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundPosition: theme => theme('positions'), - objectPosition: theme => theme('positions'), -}; -``` - -Another example is adding new properties for reference in custom plugins. For example, if you've written a gradient plugin for your project, you could add a `gradients` property to the theme object that the plugin references: - -```ts title="modern.config.ts" -const designSystem = { - gradients: theme => ({ - 'blue-green': [theme('colors.blue.500'), theme('colors.green.500')], - 'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')], - // ... - }), -}; - -export default defineConfig({ - source: { - designSystem, - }, - tools: { - tailwind: { - plugins: [require('./plugins/gradients')], - }, - }, -}); -``` - -### Configuration Reference - -In addition to `screens`, `colors`, and `spacing`, all properties in the configuration object map to core plugins in Tailwind CSS. Because many plugins are responsible for CSS properties that only accept a set of static values (e.g. `float`), not every plugin has a corresponding property in the theme object. - -All of these properties can also be extended from the default theme under the `designSystem.extend` property. - -For a complete list of all properties and their effects, see this [link](https://tailwindcss.com/docs/theme#configuration-reference). - -### Additional Configuration - -In addition to the configuration that is the same as Tailwind CSS Theme, there is additional configuration provided by Modern.js. - -#### source.designSystem.supportStyledComponents - -This configuration is of type `boolean` and defaults to `false`. - -When this configuration value is `true`, a `styled-components` `ThemeProvider` component is provided at the outermost layer of the application at runtime, and the `Theme Token` object generated through `designSystem` is injected. diff --git a/packages/document/main-doc/docs/en/configure/app/tools/tailwindcss.mdx b/packages/document/main-doc/docs/en/configure/app/tools/tailwindcss.mdx index 4a1cc34165f0..d7ef5b6f26fa 100644 --- a/packages/document/main-doc/docs/en/configure/app/tools/tailwindcss.mdx +++ b/packages/document/main-doc/docs/en/configure/app/tools/tailwindcss.mdx @@ -56,6 +56,37 @@ export default { Please note: - If you are using both the `tailwind.config.{ts,js}` file and `tools.tailwindcss` option, the configuration defined in `tools.tailwindcss` will take precedence and override the content defined in `tailwind.config.{ts,js}`. -- If you are using the [source.designSystem](/configure/app/source/design-system) configuration option simultaneously, the `theme` configuration of Tailwind CSS will be overridden by the value of `source.designSystem`. +- If you are using the `source.designSystem` configuration option simultaneously, the `theme` configuration of Tailwind CSS will be overridden by the value of `source.designSystem`. The usage of other configurations follows the same approach as the official usage of Tailwind CSS. Please refer to [tailwindcss - Configuration](https://tailwindcss.com/docs/configuration) for more details. + +### About source.designSystem + +`source.designSystem` is a deprecated configuration option in Modern.js. + +Starting from Modern.js vMAJOR_VERSION.33.0, you can use the `theme` configuration option of Tailwind CSS as a replacement for `source.designSystem`. It is no longer necessary to split the `theme` configuration and set it on `designSystem`. + +- Previous usage: + +```ts title="modern.config.ts" +const { theme, ...rest } = tailwindConfig; + +export default { + tools: { + tailwindcss: rest, + }, + source: { + designSystem: theme, + }, +}; +``` + +- Current usage: + +```ts title="modern.config.ts" +export default { + tools: { + tailwindcss: tailwindConfig, + }, +}; +``` diff --git a/packages/document/main-doc/docs/zh/configure/app/source/design-system.mdx b/packages/document/main-doc/docs/zh/configure/app/source/design-system.mdx deleted file mode 100644 index 8c9118fe3d26..000000000000 --- a/packages/document/main-doc/docs/zh/configure/app/source/design-system.mdx +++ /dev/null @@ -1,1174 +0,0 @@ ---- -sidebar_label: designSystem ---- - -# source.designSystem - -- **类型:** `Object` -- **默认值:** 见下方配置详情。 - -:::caution 注意 -需要先通过 `pnpm run new` 启用 Tailwind CSS 功能。 - -::: - -
- DesignSystem 配置详情 - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, - colors: { - transparent: 'transparent', - current: 'currentColor', - - black: '#000', - white: '#fff', - - gray: { - 100: '#f7fafc', - 200: '#edf2f7', - 300: '#e2e8f0', - 400: '#cbd5e0', - 500: '#a0aec0', - 600: '#718096', - 700: '#4a5568', - 800: '#2d3748', - 900: '#1a202c', - }, - red: { - 100: '#fff5f5', - 200: '#fed7d7', - 300: '#feb2b2', - 400: '#fc8181', - 500: '#f56565', - 600: '#e53e3e', - 700: '#c53030', - 800: '#9b2c2c', - 900: '#742a2a', - }, - orange: { - 100: '#fffaf0', - 200: '#feebc8', - 300: '#fbd38d', - 400: '#f6ad55', - 500: '#ed8936', - 600: '#dd6b20', - 700: '#c05621', - 800: '#9c4221', - 900: '#7b341e', - }, - yellow: { - 100: '#fffff0', - 200: '#fefcbf', - 300: '#faf089', - 400: '#f6e05e', - 500: '#ecc94b', - 600: '#d69e2e', - 700: '#b7791f', - 800: '#975a16', - 900: '#744210', - }, - green: { - 100: '#f0fff4', - 200: '#c6f6d5', - 300: '#9ae6b4', - 400: '#68d391', - 500: '#48bb78', - 600: '#38a169', - 700: '#2f855a', - 800: '#276749', - 900: '#22543d', - }, - teal: { - 100: '#e6fffa', - 200: '#b2f5ea', - 300: '#81e6d9', - 400: '#4fd1c5', - 500: '#38b2ac', - 600: '#319795', - 700: '#2c7a7b', - 800: '#285e61', - 900: '#234e52', - }, - blue: { - 100: '#ebf8ff', - 200: '#bee3f8', - 300: '#90cdf4', - 400: '#63b3ed', - 500: '#4299e1', - 600: '#3182ce', - 700: '#2b6cb0', - 800: '#2c5282', - 900: '#2a4365', - }, - indigo: { - 100: '#ebf4ff', - 200: '#c3dafe', - 300: '#a3bffa', - 400: '#7f9cf5', - 500: '#667eea', - 600: '#5a67d8', - 700: '#4c51bf', - 800: '#434190', - 900: '#3c366b', - }, - purple: { - 100: '#faf5ff', - 200: '#e9d8fd', - 300: '#d6bcfa', - 400: '#b794f4', - 500: '#9f7aea', - 600: '#805ad5', - 700: '#6b46c1', - 800: '#553c9a', - 900: '#44337a', - }, - pink: { - 100: '#fff5f7', - 200: '#fed7e2', - 300: '#fbb6ce', - 400: '#f687b3', - 500: '#ed64a6', - 600: '#d53f8c', - 700: '#b83280', - 800: '#97266d', - 900: '#702459', - }, - }, - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, - backgroundColor: theme => theme('colors'), - backgroundOpacity: theme => theme('opacity'), - backgroundPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundSize: { - auto: 'auto', - cover: 'cover', - contain: 'contain', - }, - borderColor: theme => ({ - ...theme('colors'), - default: theme('colors.gray.300', 'currentColor'), - }), - borderOpacity: theme => theme('opacity'), - borderRadius: { - none: '0', - sm: '0.125rem', - default: '0.25rem', - md: '0.375rem', - lg: '0.5rem', - full: '9999px', - }, - borderWidth: { - default: '1px', - 0: '0', - 2: '2px', - 4: '4px', - 8: '8px', - }, - boxShadow: { - xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', - sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', - default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', - inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', - outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', - none: 'none', - }, - container: {}, - cursor: { - auto: 'auto', - default: 'default', - pointer: 'pointer', - wait: 'wait', - text: 'text', - move: 'move', - 'not-allowed': 'not-allowed', - }, - divideColor: theme => theme('borderColor'), - divideOpacity: theme => theme('borderOpacity'), - divideWidth: theme => theme('borderWidth'), - fill: { - current: 'currentColor', - }, - flex: { - 1: '1 1 0%', - auto: '1 1 auto', - initial: '0 1 auto', - none: 'none', - }, - flexGrow: { - 0: '0', - default: '1', - }, - flexShrink: { - 0: '0', - default: '1', - }, - fontFamily: { - sans: [ - 'system-ui', - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - '"Noto Sans"', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - '"Noto Color Emoji"', - ], - serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], - mono: [ - 'Menlo', - 'Monaco', - 'Consolas', - '"Liberation Mono"', - '"Courier New"', - 'monospace', - ], - }, - fontSize: { - xs: '0.75rem', - sm: '0.875rem', - base: '1rem', - lg: '1.125rem', - xl: '1.25rem', - '2xl': '1.5rem', - '3xl': '1.875rem', - '4xl': '2.25rem', - '5xl': '3rem', - '6xl': '4rem', - }, - fontWeight: { - hairline: '100', - thin: '200', - light: '300', - normal: '400', - medium: '500', - semibold: '600', - bold: '700', - extrabold: '800', - black: '900', - }, - height: theme => ({ - auto: 'auto', - ...theme('spacing'), - full: '100%', - screen: '100vh', - }), - inset: { - 0: '0', - auto: 'auto', - }, - letterSpacing: { - tighter: '-0.05em', - tight: '-0.025em', - normal: '0', - wide: '0.025em', - wider: '0.05em', - widest: '0.1em', - }, - lineHeight: { - none: '1', - tight: '1.25', - snug: '1.375', - normal: '1.5', - relaxed: '1.625', - loose: '2', - 3: '.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 7: '1.75rem', - 8: '2rem', - 9: '2.25rem', - 10: '2.5rem', - }, - listStyleType: { - none: 'none', - disc: 'disc', - decimal: 'decimal', - }, - margin: (theme, { negative }) => ({ - auto: 'auto', - ...theme('spacing'), - ...negative(theme('spacing')), - }), - maxHeight: { - full: '100%', - screen: '100vh', - }, - maxWidth: (theme, { breakpoints }) => ({ - none: 'none', - xs: '20rem', - sm: '24rem', - md: '28rem', - lg: '32rem', - xl: '36rem', - '2xl': '42rem', - '3xl': '48rem', - '4xl': '56rem', - '5xl': '64rem', - '6xl': '72rem', - full: '100%', - ...breakpoints(theme('screens')), - }), - minHeight: { - 0: '0', - full: '100%', - screen: '100vh', - }, - minWidth: { - 0: '0', - full: '100%', - }, - objectPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - opacity: { - 0: '0', - 25: '0.25', - 50: '0.5', - 75: '0.75', - 100: '1', - }, - order: { - first: '-9999', - last: '9999', - none: '0', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - }, - padding: theme => theme('spacing'), - placeholderColor: theme => theme('colors'), - placeholderOpacity: theme => theme('opacity'), - space: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - }), - stroke: { - current: 'currentColor', - }, - strokeWidth: { - 0: '0', - 1: '1', - 2: '2', - }, - textColor: theme => theme('colors'), - textOpacity: theme => theme('opacity'), - width: theme => ({ - auto: 'auto', - ...theme('spacing'), - '1/2': '50%', - '1/3': '33.333333%', - '2/3': '66.666667%', - '1/4': '25%', - '2/4': '50%', - '3/4': '75%', - '1/5': '20%', - '2/5': '40%', - '3/5': '60%', - '4/5': '80%', - '1/6': '16.666667%', - '2/6': '33.333333%', - '3/6': '50%', - '4/6': '66.666667%', - '5/6': '83.333333%', - '1/12': '8.333333%', - '2/12': '16.666667%', - '3/12': '25%', - '4/12': '33.333333%', - '5/12': '41.666667%', - '6/12': '50%', - '7/12': '58.333333%', - '8/12': '66.666667%', - '9/12': '75%', - '10/12': '83.333333%', - '11/12': '91.666667%', - full: '100%', - screen: '100vw', - }), - zIndex: { - auto: 'auto', - 0: '0', - 10: '10', - 20: '20', - 30: '30', - 40: '40', - 50: '50', - }, - gap: theme => theme('spacing'), - gridTemplateColumns: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - 7: 'repeat(7, minmax(0, 1fr))', - 8: 'repeat(8, minmax(0, 1fr))', - 9: 'repeat(9, minmax(0, 1fr))', - 10: 'repeat(10, minmax(0, 1fr))', - 11: 'repeat(11, minmax(0, 1fr))', - 12: 'repeat(12, minmax(0, 1fr))', - }, - gridColumn: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - 'span-7': 'span 7 / span 7', - 'span-8': 'span 8 / span 8', - 'span-9': 'span 9 / span 9', - 'span-10': 'span 10 / span 10', - 'span-11': 'span 11 / span 11', - 'span-12': 'span 12 / span 12', - }, - gridColumnStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridColumnEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridTemplateRows: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - }, - gridRow: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - }, - gridRowStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - gridRowEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - transformOrigin: { - center: 'center', - top: 'top', - 'top-right': 'top right', - right: 'right', - 'bottom-right': 'bottom right', - bottom: 'bottom', - 'bottom-left': 'bottom left', - left: 'left', - 'top-left': 'top left', - }, - scale: { - 0: '0', - 50: '.5', - 75: '.75', - 90: '.9', - 95: '.95', - 100: '1', - 105: '1.05', - 110: '1.1', - 125: '1.25', - 150: '1.5', - }, - rotate: { - '-180': '-180deg', - '-90': '-90deg', - '-45': '-45deg', - 0: '0', - 45: '45deg', - 90: '90deg', - 180: '180deg', - }, - translate: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - '-full': '-100%', - '-1/2': '-50%', - '1/2': '50%', - full: '100%', - }), - skew: { - '-12': '-12deg', - '-6': '-6deg', - '-3': '-3deg', - 0: '0', - 3: '3deg', - 6: '6deg', - 12: '12deg', - }, - transitionProperty: { - none: 'none', - all: 'all', - default: - 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', - colors: 'background-color, border-color, color, fill, stroke', - opacity: 'opacity', - shadow: 'box-shadow', - transform: 'transform', - }, - transitionTimingFunction: { - linear: 'linear', - in: 'cubic-bezier(0.4, 0, 1, 1)', - out: 'cubic-bezier(0, 0, 0.2, 1)', - 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', - }, - transitionDuration: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, - transitionDelay: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, -}; -``` -
- -:::tip 提示 -更多关于 Tailwind CSS 配置可查看[这里](https://tailwindcss.com/docs/configuration#theme)。 - -::: - -`designSystem` 用于定义项目的调色板、排版比例(Typographic Scales 或者 Type Scale)、字体列表、断点、边框圆角值等等。因为 Modern.js 借用了 Tailwind Theme 的设计方式,并且内部也集成了 Tailwind CSS,所以 `designSystem` 使用方式与 Tailwind CSS Theme 相同。 - -### 结构 - -`designSystem` 对象包含 `screens`、`colors` 和 `spacing` 的属性,以及每个可自定义核心插件。 - -#### Screens - -使用 `screens` 可以自定义项目中的响应断点: - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, -}; -``` - -其中 `screens` 对象里的属性名是屏幕名称(用作 `Tailwind CSS` 生成的自适应实用程序变体的前缀,例如 `md:text-center`),值是该断点应在其开始的 `min-width`。 - -默认断点受常见设备分辨率的启发: - -```js -const designSystem = { - screens: { - sm: '640px', - // => @media (min-width: 640px) { ... } - - md: '768px', - // => @media (min-width: 768px) { ... } - - lg: '1024px', - // => @media (min-width: 1024px) { ... } - - xl: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -你可以在你的项目中使用任意你喜欢的名称作为断点的属性: - -```js -const designSystem = { - screens: { - tablet: '640px', - // => @media (min-width: 640px) { ... } - - laptop: '1024px', - // => @media (min-width: 1024px) { ... } - - desktop: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -这些屏幕名称反映在 `utilities` 中,因此 `text-center` 现在是这样的: - -```css -.text-center { - text-align: center; -} - -@media (min-width: 640px) { - .tablet\:text-center { - text-align: center; - } -} - -@media (min-width: 1024px) { - .laptop\:text-center { - text-align: center; - } -} - -@media (min-width: 1280px) { - .desktop\:text-center { - text-align: center; - } -} -``` - -##### Max-width 断点 - -如果要使用 `max-width` 断点而不是 `min-width`,可以将屏幕指定为具有 `max` 属性的对象: - -```js -const designSystem = { - screens: { - xl: { max: '1279px' }, - // => @media (max-width: 1279px) { ... } - - lg: { max: '1023px' }, - // => @media (max-width: 1023px) { ... } - - md: { max: '767px' }, - // => @media (max-width: 767px) { ... } - - sm: { max: '639px' }, - // => @media (max-width: 639px) { ... } - }, -}; -``` - -如有必要,以创建带有 `min-width` 和 `max-width` 定义的断点,例如: - -```js -const designSystem = { - screens: { - sm: { min: '640px', max: '767px' }, - md: { min: '768px', max: '1023px' }, - lg: { min: '1024px', max: '1279px' }, - xl: { min: '1280px' }, - }, -}; -``` - -##### 多个范围的断点 - -有时,将单个断点定义应用于多个范围会很有用。 - -例如,假设您有一个 `sidebar`,并且希望断点基于内容区域宽度而不是整个视口。您可以模拟这种情况,当 `sidebar` 可见并缩小内容区域时,断点的样式使用较小的断点样式: - -```js -const designSystem = { - screens: { - sm: '500px', - md: [ - // Sidebar appears at 768px, so revert to `sm:` styles between 768px - // and 868px, after which the main content area is wide enough again to - // apply the `md:` styles. - { min: '668px', max: '767px' }, - { min: '868px' }, - ], - lg: '1100px', - xl: '1400px', - }, -}; -``` - -##### 自定义媒体查询 - -如果需要为断点提供完全自定义的媒体查询,则可以使用带有 `raw` 属性的对象: - -```js -const designSystem = { - extend: { - screens: { - portrait: { raw: '(orientation: portrait)' }, - // => @media (orientation: portrait) { ... } - }, - }, -}; -``` - -##### Print 样式 - -如果需要为打印应用不同的样式,则 `raw` 选项可能特别有用。 - -需要做的就是在 `designSystem.extend.screens` 下添加一个 `print`: - -```js -const designSystem = { - extend: { - screens: { - print: { raw: 'print' }, - // => @media print { ... } - }, - }, -}; -``` - -然后,可以使用诸如 `print:text-black` 之类的类来指定仅当某人尝试打印页面时才应用的样式: - -```html -
- {/* ... */} -
-``` - -##### Dark Mode - -`raw` 选项可以用于实现 “暗模式” 屏幕: - -```js -const designSystem = { - extend: { - screens: { - dark: { raw: '(prefers-color-scheme: dark)' }, - // => @media (prefers-color-scheme: dark) { ... } - }, - }, -}; -``` - -然后,您可以使用 `dark:` 前缀在暗模式下为元素设置不同的样式: - -```html -
- {/* ... */} -
-``` - -请注意,由于这些 `screen variants` 是在 `Tailwind CSS` 中实现的,因此**无法使用这种方法将断点与暗模式结合使用** ,例如 `md:dark:text-gray-300` 将不起作用。 - -#### Colors - -`colors` 属性可让您自定义项目的全局调色板。 - -```js -const designSystem = { - colors: { - transparent: 'transparent', - black: '#000', - white: '#fff', - gray: { - 100: '#f7fafc', - // ... - 900: '#1a202c', - }, - - // ... - }, -}; -``` - -默认情况下,这些颜色由 `backgroundColor`,`textColor` 和 `borderColor` 核心插件继承。 - -想了解更多,可以查看:[Customizing Colors](https://tailwindcss.com/docs/customizing-colors)。 - -#### Spacing - -使用 `space` 属性,可以自定义项目的全局间距和缩放比例: - -```js -const designSystem = { - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, -}; -``` - -默认情况下,这些值由 `padding`,`margin`,`negativeMargin`,`width` 和 `height` 核心插件继承。 - -想要了解更多,看 [Customizing Spacing](https://tailwindcss.com/docs/customizing-spacing)。 - -#### Core plugins - -主题部分的其余部分用于配置每个核心插件可用的值。 - -例如,`borderRadius` 属性可让您自定义将生成的圆角的 `utilities`: - -```js -const designSystem = { - borderRadius: { - none: '0', - sm: '.125rem', - default: '.25rem', - lg: '.5rem', - full: '9999px', - }, -}; -``` - -**属性名确定所生成类的后缀,值确定实际 CSS 声明的值。**上面的示例 `borderRadius` 配置将生成以下 CSS 类: - -```css -.rounded-none { - border-radius: 0; -} -.rounded-sm { - border-radius: 0.125rem; -} -.rounded { - border-radius: 0.25rem; -} -.rounded-lg { - border-radius: 0.5rem; -} -.rounded-full { - border-radius: 9999px; -} -``` - -会注意到,在主题配置中使用 `default` 属性创建了不带后缀的 `rounded` 类。这是许多(尽管不是全部)核心插件支持的 Tailwind CSS 中的通用约定。 - -要了解有关自定义特定核心插件的更多信息,请访问该插件的文档。 - -### 自定义默认配置 - -开箱即用,您的项目将自动从默认主题配置继承值。如果想自定义默认主题,则根据目标有几种不同的选择。 - -#### 覆盖默认配置 - -要覆盖默认配置中的选项,请在 `designSystem` 中添加要覆盖的属性: - -```ts title="modern.config.ts" -const designSystem = { - // Replaces all of the default `opacity` values - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -这将完全替换默认属性配置,因此在上面的示例中,不会生成默认的 `opacity utilities`。 - -您未提供的任何属性都将从默认主题继承,因此在上面的示例中,将保留颜色,间距,边框圆角,背景位置等内容的默认主题配置。 - -#### 扩展默认配置 - -如果您想保留主题选项的默认值,但又要添加新值,请在 `designSystem.extend` 属性下添加扩展的内容。 - -例如,如果您想添加一个额外的断点但保留现有的断点,则可以扩展 `screens` 属性: - -```ts title="modern.config.ts" -const designSystem = { - extend: { - // Adds a new breakpoint in addition to the default breakpoints - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -您当然可以覆盖默认主题的某些部分,并在同一配置中扩展默认主题的其他部分: - -```ts title="modern.config.ts" -const designSystem = { - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, - extend: { - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -#### 引用其他值 - -如果需要在配置中引用另一个值,可以通过提供闭包函数而不是静态值来实现。函数将收到 `theme()` 函数作为参数,您可以使用该函数使用点表示法在配置中查找其他值。 - -例如,您可以在 `fill` 配置上通过引用 `theme('colors')` 为调色板中的每种颜色生成 `fill` utilities。 - -```ts title="modern.config.ts" -const designSystem = { - colors: { - // ... - }, - fill: theme => theme('colors'), -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -`theme()`函数尝试从已经完全合并的配置对象中找到您要查找的值,因此它可以引用您自己的自定义设置以及默认主题值。它也可以递归工作,因此只要链末尾有一个静态值,它就可以解析您要查找的值。 - -**引用默认配置** - -如果出于任何原因想要引用默认配置中的值,则可以从 `tailwindcss/defaultTheme` 导入它。一个有用的示例是,如果要将添加默认配置提供的字体中某一个字体: - -```ts title="modern.config.ts" -const defaultTheme = require('tailwindcss/defaultTheme'); - -const designSystem = { - extend: { - fontFamily: { - sans: ['Lato', ...defaultTheme.fontFamily.sans], - }, - }, -}; - -export default defineConfig({ - source: { - designSystem, - }, -}); -``` - -#### 禁用整个核心插件 - -如果您不想为某个核心插件生成任何类,则最好在 `corePlugins` 配置中将该插件设置为 `false`,而不是在配置中为该属性提供一个空对象: - -```js -// Don't assign an empty object in your theme configuration - -const designSystem = { - opacity: {}, -}; - -// Do disable the plugin in your corePlugins configuration -const designSyttem = { - corePlugins: { - opacity: false, - }, -}; -``` - -最终结果是相同的,但是由于许多核心插件未公开任何配置,因此无论如何只能使用 corePlugins 禁用它们,最好保持一致。 - -#### 添加自己的 key - -在很多情况下,将自己的属性添加到配置对象可能会很有用。 - -其中一个示例是添加新属性为多个核心插件之间复用。例如,您可以提取一个 `positions`对象,`backgroundPosition` 和 `objectPosition` 插件都可以引用该对象: - -```js -const designSystem = { - positions: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundPosition: theme => theme('positions'), - objectPosition: theme => theme('positions'), -}; -``` - -另一个示例是在自定义插件中添加新的属性以进行引用。例如,如果您为项目编写了渐变插件,则可以向该插件引用的主题对象添加渐变属性: - -```ts title="modern.config.ts" -const designSystem = { - gradients: theme => ({ - 'blue-green': [theme('colors.blue.500'), theme('colors.green.500')], - 'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')], - // ... - }), -}; - -export default defineConfig({ - source: { - designSystem, - }, - tools: { - tailwind: { - plugins: [require('./plugins/gradients')], - }, - }, -}); -``` - -### 配置引用 - -除了 `screens`,`colors` 和 `spacing` 外,配置对象中的所有属性都映射到 `Tailwind CSS` 的核心插件上。由于许多插件负责仅接受静态值集(例如,例如`float`)的 CSS 属性,因此请注意,并非每个插件在主题对象中都有对应的属性。 - -所有这些属性也可以在 `designSystem.extend` 属性下使用,以扩展默认主题。 - -关于所有属性的作用,可以查看此 [链接](https://tailwindcss.com/docs/theme#configuration-reference)。 - -### 额外的配置 - -除了与 Tailwind CSS Theme 相同的配置以外,还有 Modern.js 提供的额外的配置。 - -#### source.designSystem.supportStyledComponents - -该配置类型为 `boolean`,默认为 `false`。 - -当该配置值为 `true` 时,运行时在应用外层提供 `styled-components` `ThemeProvider` 组件,并且将通过 `designSystem` 生成的 `Theme Token` 对象注入。 diff --git a/packages/document/main-doc/docs/zh/configure/app/tools/tailwindcss.mdx b/packages/document/main-doc/docs/zh/configure/app/tools/tailwindcss.mdx index 3b495a328f03..57a2e186344e 100644 --- a/packages/document/main-doc/docs/zh/configure/app/tools/tailwindcss.mdx +++ b/packages/document/main-doc/docs/zh/configure/app/tools/tailwindcss.mdx @@ -56,6 +56,37 @@ export default { 注意: - 如果你同时使用了 `tailwind.config.{ts,js}` 文件和 `tools.tailwindcss` 选项,那么 `tools.tailwindcss` 定义的配置会优先生效,并覆盖 `tailwind.config.{ts,js}` 中定义的内容。 -- 如果你同时使用了 [source.designSystem](/configure/app/source/design-system) 配置项,那么 Tailwind CSS 的 `theme` 配置将会被 `source.designSystem` 的值所覆盖。 +- 如果你同时使用了 `source.designSystem` 配置项,那么 Tailwind CSS 的 `theme` 配置将会被 `source.designSystem` 的值所覆盖。 其他配置的使用方式与 Tailwind CSS 官方用法一致,请参考 [tailwindcss - Configuration](https://tailwindcss.com/docs/configuration)。 + +### 关于 source.designSystem + +`source.designSystem` 是 Modern.js 中废弃的配置项。 + +从 Modern.js vMAJOR_VERSION.33.0 版本开始,你可以使用 Tailwind CSS 的 `theme` 配置项来代替 `source.designSystem`,不再需要将 `theme` 配置拆分并设置到 `designSystem` 上。 + +- 旧版本用法: + +```ts title="modern.config.ts" +const { theme, ...rest } = tailwindConfig; + +export default { + tools: { + tailwindcss: rest, + }, + source: { + designSystem: theme, + }, +}; +``` + +- 当前版本用法: + +```ts title="modern.config.ts" +export default { + tools: { + tailwindcss: tailwindConfig, + }, +}; +``` diff --git a/packages/document/module-doc/docs/en/api/config/build-config.mdx b/packages/document/module-doc/docs/en/api/config/build-config.mdx index b3e2d159a868..366fa2e75be8 100644 --- a/packages/document/module-doc/docs/en/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/en/api/config/build-config.mdx @@ -1111,7 +1111,7 @@ The rest of the usage is the same as Tailwind CSS: [Quick Portal](https://tailwi Please note that: - If you are using both the `tailwind.config.{ts,js}` file and `tools.tailwindcss` option, the configuration defined in `tools.tailwindcss` will take precedence and override the content defined in `tailwind.config.{ts,js}`. -- If you are using the [designSystem](/api/config/design-system) configuration option simultaneously, the `theme` configuration of Tailwind CSS will be overridden by the value of `designSystem`. +- If you are using the `designSystem` configuration option simultaneously, the `theme` configuration of Tailwind CSS will be overridden by the value of `designSystem`. The usage of other configurations follows the same approach as the official usage of Tailwind CSS. Please refer to [tailwindcss - Configuration](https://tailwindcss.com/docs/configuration) for more details. @@ -1260,7 +1260,7 @@ At this point the umd artifact will go to mount on `global.myLib` - The module name of the umd artifact must not conflict with the global variable name. - Module names will be converted to camelCase, e.g. `my-lib` will be converted to `myLib`, refer to [toIdentifier](https://github.com/babel/babel/blob/main/packages/babel-types/src/converters/toIdentifier.ts). -::: + ::: Also the function form can take one parameter, which is the output path of the current package file diff --git a/packages/document/module-doc/docs/en/api/config/design-system.md b/packages/document/module-doc/docs/en/api/config/design-system.md deleted file mode 100644 index aec4b0c57ec9..000000000000 --- a/packages/document/module-doc/docs/en/api/config/design-system.md +++ /dev/null @@ -1,1166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# designSystem - -This chapter describes the configuration related to designSystem. - -:::tip -The Tailwind CSS feature needs to be enabled first via `pnpm run new`. -::: - -- Type: `object` -- Default: `see configuration details below`. - -
- designSystem configuration details - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, - colors: { - transparent: 'transparent', - current: 'currentColor', - - black: '#000', - white: '#fff', - - gray: { - 100: '#f7fafc', - 200: '#edf2f7', - 300: '#e2e8f0', - 400: '#cbd5e0', - 500: '#a0aec0', - 600: '#718096', - 700: '#4a5568', - 800: '#2d3748', - 900: '#1a202c', - }, - red: { - 100: '#fff5f5', - 200: '#fed7d7', - 300: '#feb2b2', - 400: '#fc8181', - 500: '#f56565', - 600: '#e53e3e', - 700: '#c53030', - 800: '#9b2c2c', - 900: '#742a2a', - }, - orange: { - 100: '#fffaf0', - 200: '#feebc8', - 300: '#fbd38d', - 400: '#f6ad55', - 500: '#ed8936', - 600: '#dd6b20', - 700: '#c05621', - 800: '#9c4221', - 900: '#7b341e', - }, - yellow: { - 100: '#fffff0', - 200: '#fefcbf', - 300: '#faf089', - 400: '#f6e05e', - 500: '#ecc94b', - 600: '#d69e2e', - 700: '#b7791f', - 800: '#975a16', - 900: '#744210', - }, - green: { - 100: '#f0fff4', - 200: '#c6f6d5', - 300: '#9ae6b4', - 400: '#68d391', - 500: '#48bb78', - 600: '#38a169', - 700: '#2f855a', - 800: '#276749', - 900: '#22543d', - }, - teal: { - 100: '#e6fffa', - 200: '#b2f5ea', - 300: '#81e6d9', - 400: '#4fd1c5', - 500: '#38b2ac', - 600: '#319795', - 700: '#2c7a7b', - 800: '#285e61', - 900: '#234e52', - }, - blue: { - 100: '#ebf8ff', - 200: '#bee3f8', - 300: '#90cdf4', - 400: '#63b3ed', - 500: '#4299e1', - 600: '#3182ce', - 700: '#2b6cb0', - 800: '#2c5282', - 900: '#2a4365', - }, - indigo: { - 100: '#ebf4ff', - 200: '#c3dafe', - 300: '#a3bffa', - 400: '#7f9cf5', - 500: '#667eea', - 600: '#5a67d8', - 700: '#4c51bf', - 800: '#434190', - 900: '#3c366b', - }, - purple: { - 100: '#faf5ff', - 200: '#e9d8fd', - 300: '#d6bcfa', - 400: '#b794f4', - 500: '#9f7aea', - 600: '#805ad5', - 700: '#6b46c1', - 800: '#553c9a', - 900: '#44337a', - }, - pink: { - 100: '#fff5f7', - 200: '#fed7e2', - 300: '#fbb6ce', - 400: '#f687b3', - 500: '#ed64a6', - 600: '#d53f8c', - 700: '#b83280', - 800: '#97266d', - 900: '#702459', - }, - }, - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, - backgroundColor: theme => theme('colors'), - backgroundOpacity: theme => theme('opacity'), - backgroundPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundSize: { - auto: 'auto', - cover: 'cover', - contain: 'contain', - }, - borderColor: theme => ({ - ...theme('colors'), - default: theme('colors.gray.300', 'currentColor'), - }), - borderOpacity: theme => theme('opacity'), - borderRadius: { - none: '0', - sm: '0.125rem', - default: '0.25rem', - md: '0.375rem', - lg: '0.5rem', - full: '9999px', - }, - borderWidth: { - default: '1px', - 0: '0', - 2: '2px', - 4: '4px', - 8: '8px', - }, - boxShadow: { - xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', - sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', - default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', - inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', - outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', - none: 'none', - }, - container: {}, - cursor: { - auto: 'auto', - default: 'default', - pointer: 'pointer', - wait: 'wait', - text: 'text', - move: 'move', - 'not-allowed': 'not-allowed', - }, - divideColor: theme => theme('borderColor'), - divideOpacity: theme => theme('borderOpacity'), - divideWidth: theme => theme('borderWidth'), - fill: { - current: 'currentColor', - }, - flex: { - 1: '1 1 0%', - auto: '1 1 auto', - initial: '0 1 auto', - none: 'none', - }, - flexGrow: { - 0: '0', - default: '1', - }, - flexShrink: { - 0: '0', - default: '1', - }, - fontFamily: { - sans: [ - 'system-ui', - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - '"Noto Sans"', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - '"Noto Color Emoji"', - ], - serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], - mono: [ - 'Menlo', - 'Monaco', - 'Consolas', - '"Liberation Mono"', - '"Courier New"', - 'monospace', - ], - }, - fontSize: { - xs: '0.75rem', - sm: '0.875rem', - base: '1rem', - lg: '1.125rem', - xl: '1.25rem', - '2xl': '1.5rem', - '3xl': '1.875rem', - '4xl': '2.25rem', - '5xl': '3rem', - '6xl': '4rem', - }, - fontWeight: { - hairline: '100', - thin: '200', - light: '300', - normal: '400', - medium: '500', - semibold: '600', - bold: '700', - extrabold: '800', - black: '900', - }, - height: theme => ({ - auto: 'auto', - ...theme('spacing'), - full: '100%', - screen: '100vh', - }), - inset: { - 0: '0', - auto: 'auto', - }, - letterSpacing: { - tighter: '-0.05em', - tight: '-0.025em', - normal: '0', - wide: '0.025em', - wider: '0.05em', - widest: '0.1em', - }, - lineHeight: { - none: '1', - tight: '1.25', - snug: '1.375', - normal: '1.5', - relaxed: '1.625', - loose: '2', - 3: '.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 7: '1.75rem', - 8: '2rem', - 9: '2.25rem', - 10: '2.5rem', - }, - listStyleType: { - none: 'none', - disc: 'disc', - decimal: 'decimal', - }, - margin: (theme, { negative }) => ({ - auto: 'auto', - ...theme('spacing'), - ...negative(theme('spacing')), - }), - maxHeight: { - full: '100%', - screen: '100vh', - }, - maxWidth: (theme, { breakpoints }) => ({ - none: 'none', - xs: '20rem', - sm: '24rem', - md: '28rem', - lg: '32rem', - xl: '36rem', - '2xl': '42rem', - '3xl': '48rem', - '4xl': '56rem', - '5xl': '64rem', - '6xl': '72rem', - full: '100%', - ...breakpoints(theme('screens')), - }), - minHeight: { - 0: '0', - full: '100%', - screen: '100vh', - }, - minWidth: { - 0: '0', - full: '100%', - }, - objectPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - opacity: { - 0: '0', - 25: '0.25', - 50: '0.5', - 75: '0.75', - 100: '1', - }, - order: { - first: '-9999', - last: '9999', - none: '0', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - }, - padding: theme => theme('spacing'), - placeholderColor: theme => theme('colors'), - placeholderOpacity: theme => theme('opacity'), - space: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - }), - stroke: { - current: 'currentColor', - }, - strokeWidth: { - 0: '0', - 1: '1', - 2: '2', - }, - textColor: theme => theme('colors'), - textOpacity: theme => theme('opacity'), - width: theme => ({ - auto: 'auto', - ...theme('spacing'), - '1/2': '50%', - '1/3': '33.333333%', - '2/3': '66.666667%', - '1/4': '25%', - '2/4': '50%', - '3/4': '75%', - '1/5': '20%', - '2/5': '40%', - '3/5': '60%', - '4/5': '80%', - '1/6': '16.666667%', - '2/6': '33.333333%', - '3/6': '50%', - '4/6': '66.666667%', - '5/6': '83.333333%', - '1/12': '8.333333%', - '2/12': '16.666667%', - '3/12': '25%', - '4/12': '33.333333%', - '5/12': '41.666667%', - '6/12': '50%', - '7/12': '58.333333%', - '8/12': '66.666667%', - '9/12': '75%', - '10/12': '83.333333%', - '11/12': '91.666667%', - full: '100%', - screen: '100vw', - }), - zIndex: { - auto: 'auto', - 0: '0', - 10: '10', - 20: '20', - 30: '30', - 40: '40', - 50: '50', - }, - gap: theme => theme('spacing'), - gridTemplateColumns: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - 7: 'repeat(7, minmax(0, 1fr))', - 8: 'repeat(8, minmax(0, 1fr))', - 9: 'repeat(9, minmax(0, 1fr))', - 10: 'repeat(10, minmax(0, 1fr))', - 11: 'repeat(11, minmax(0, 1fr))', - 12: 'repeat(12, minmax(0, 1fr))', - }, - gridColumn: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - 'span-7': 'span 7 / span 7', - 'span-8': 'span 8 / span 8', - 'span-9': 'span 9 / span 9', - 'span-10': 'span 10 / span 10', - 'span-11': 'span 11 / span 11', - 'span-12': 'span 12 / span 12', - }, - gridColumnStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridColumnEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridTemplateRows: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - }, - gridRow: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - }, - gridRowStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - gridRowEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - transformOrigin: { - center: 'center', - top: 'top', - 'top-right': 'top right', - right: 'right', - 'bottom-right': 'bottom right', - bottom: 'bottom', - 'bottom-left': 'bottom left', - left: 'left', - 'top-left': 'top left', - }, - scale: { - 0: '0', - 50: '.5', - 75: '.75', - 90: '.9', - 95: '.95', - 100: '1', - 105: '1.05', - 110: '1.1', - 125: '1.25', - 150: '1.5', - }, - rotate: { - '-180': '-180deg', - '-90': '-90deg', - '-45': '-45deg', - 0: '0', - 45: '45deg', - 90: '90deg', - 180: '180deg', - }, - translate: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - '-full': '-100%', - '-1/2': '-50%', - '1/2': '50%', - full: '100%', - }), - skew: { - '-12': '-12deg', - '-6': '-6deg', - '-3': '-3deg', - 0: '0', - 3: '3deg', - 6: '6deg', - 12: '12deg', - }, - transitionProperty: { - none: 'none', - all: 'all', - default: - 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', - colors: 'background-color, border-color, color, fill, stroke', - opacity: 'opacity', - shadow: 'box-shadow', - transform: 'transform', - }, - transitionTimingFunction: { - linear: 'linear', - in: 'cubic-bezier(0.4, 0, 1, 1)', - out: 'cubic-bezier(0, 0, 0.2, 1)', - 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', - }, - transitionDuration: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, - transitionDelay: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, -}; -``` - -:::tip -More about [Tailwind CSS configuration](https://tailwindcss.com/docs/configuration#theme) -::: - -
- -The `designSystem` is used to define the project's color palette, typographic scales (Typographic Scales or Type Scale), font list, breakpoints, border rounding values, etc. Since Modern.js borrows the design approach from Tailwind Theme and integrates with Tailwind CSS internally, `designSystem` is used in the same way as Tailwind CSS Theme - -The `designSystem` object contains the `screens`, `colors` and `spacing` properties, as well as each customizable core plugin. - -## Screens - -The responsive breakpoints in your project can be customized using `screens`: the - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, -}; -``` - -where the property name in the `screens` object is the screen name (used as a prefix for the adaptive utility variants generated by `Tailwind CSS`, e.g. `md:text-center`) and the value is the `min-width` at which the breakpoint should start. - -Default breakpoints are inspired by common device resolutions: the - -```js -const designSystem = { - screens: { - sm: '640px', - // => @media (min-width: 640px) { ... } - - md: '768px', - // => @media (min-width: 768px) { ... } - - lg: '1024px', - // => @media (min-width: 1024px) { ... } - - xl: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -You can use any name you like as a breakpoint property in your project: the - -```js -const designSystem = { - screens: { - tablet: '640px', - // => @media (min-width: 640px) { ... } - - laptop: '1024px', - // => @media (min-width: 1024px) { ... } - - desktop: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -These screen names are reflected in `utilities`, so `text-center` now looks like this - -```css -.text-center { - text-align: center; -} - -@media (min-width: 640px) { - .tablet\:text-center { - text-align: center; - } -} - -@media (min-width: 1024px) { - .laptop\:text-center { - text-align: center; - } -} - -@media (min-width: 1280px) { - .desktop\:text-center { - text-align: center; - } -} -``` - -### Max-width breakpoints - -To use the `max-width` breakpoint instead of `min-width`, you can specify the screen as an object with the `max` attribute. - -```js -const designSystem = { - screens: { - xl: { max: '1279px' } - // => @media (max-width: 1279px) { ... } - - lg: { max: '1023px' }, - // => @media (max-width: 1023px) { ... } - - md: { max: '767px' }, - // => @media (max-width: 767px) { ... } - - sm: { max: '639px' }, - // => @media (max-width: 639px) { ... } - }, -}; -``` - -If necessary, to create breakpoints with `min-width` and `max-width` definitions, e.g. - -```js -const designSystem = { - screens: { - sm: { min: '640px', max: '767px' } - md: { min: '768px', max: '1023px' } - lg: { min: '1024px', max: '1279px' }, lg: { min: '1024px', max: '1279px' }, - xl: { min: '1280px' } - }, -}; -``` - -### Multiple range breakpoints - -Sometimes it can be useful to apply a single breakpoint definition to multiple scopes. - -For example, suppose you have a `sidebar` and want the breakpoint to be based on the width of the content area rather than the entire viewport. You can simulate this situation by using a smaller breakpoint style when the `sidebar` is visible and the content area is narrowed: the - -```js -const designSystem = { - screens: { - sm: '500px', - md: [ - // Sidebar appears at 768px, so revert to `sm:` styles between 768px - // and 868px, after which the main content area is wide enough again to - // apply the `md:` styles. - { min: '668px', max: '767px' } - { min: '868px' }, { min: '868px' }, - ], - lg: '1100px', - xl: '1400px', - }, -}; -``` - -### Custom media queries - -If a fully customizable media query is required for a breakpoint, an object with the `raw` attribute can be used. - -```js -const designSystem = { - extend: { - screens: { - portrait: { raw: '(orientation: portrait)' }, - // => @media (orientation: portrait) { ... } - }, - }, -}; -``` - -### Print styles - -The `raw` option may be particularly useful if you need to apply different styles to printing. - -All that needs to be done is to add a `print` under `designSystem.extend.screens`. - -```js -const designSystem = { - extend: { - screens: { - print: { raw: 'print' }, - // => @media print { ... } - }, - }, -}; -``` - -Then, a class such as `print:text-black` can be used to specify a style that is applied only when someone tries to print a page: `` - -```html -
- -
-``` - -### Dark Mode - -`raw` 选项可以用于实现 “暗模式” 屏幕: - -```js -const designSystem = { - extend: { - screens: { - dark: { raw: '(prefers-color-scheme: dark)' }, - // => @media (prefers-color-scheme: dark) { ... } - }, - }, -}; -``` - -然后,您可以使用 `dark:` 前缀在暗模式下为元素设置不同的样式: - -```html -
- -
-``` - -请注意,由于这些 `screen variants` 是在 `Tailwind CSS` 中实现的,因此**无法使用这种方法将断点与暗模式结合使用** ,例如 `md:dark:text-gray-300` 将不起作用。 - -## Colors - -`colors` 属性可让您自定义项目的全局调色板。 - -```js -const designSystem = { - colors: { - transparent: 'transparent', - black: '#000', - white: '#fff', - gray: { - 100: '#f7fafc', - // ... - 900: '#1a202c', - }, - - // ... - }, -}; -``` - -By default, these colors are inherited by the `backgroundColor`, `textColor` and `borderColor` core plugins. - -To learn more, you can check out: [Customizing Colors](https://tailwindcss.com/docs/customizing-colors). - -## Spacing - -The global spacing and scaling of items can be customized using the `space` attribute: the - -```js -const designSystem = { - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, -}; -``` - -By default, these values are inherited by the `padding`, `margin`, `negativeMargin`, `width` and `height` core plugins. - -To learn more, see [Customizing Spacing](https://tailwindcss.com/docs/customizing-spacing). - -## Core plugins - -The rest of the theme section is used to configure the values available for each core plugin. - -For example, the `borderRadius` property allows you to customize the ``utilities` that will generate the rounded corners. - -```js -const designSystem = { - borderRadius: { - none: '0', - sm: '.125rem', - default: '.25rem', - lg: '.5rem', - full: '9999px', - }, -}; -``` - -** The attribute name determines the suffix of the generated class, and the value determines the value of the actual CSS declaration. ** -The example `borderRadius` configuration above will generate the following CSS classes. - -```css -.rounded-none { - border-radius: 0; -} -.rounded-sm { - border-radius: 0.125rem; -} -.rounded { - border-radius: 0.25rem; -} -.rounded-lg { - border-radius: 0.5rem; -} -.rounded-full { - border-radius: 9999px; -} -``` - -You will notice that the `rounded` class is created without the suffix in the theme configuration using the `default` attribute. This is a common convention in Tailwind CSS supported by many (though not all) of the core plugins. - -To learn more about customizing a specific core plugin, please visit the documentation for that plugin. - -## Customizing the default configuration - -Out of the box, your project will automatically inherit values from the default theme configuration. If you want to customize the default theme, there are several different options depending on the goal. - -### Override the default configuration - -To override the options in the default configuration, add the properties to be overridden to `designSystem` at - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - // Replaces all of the default `opacity` values - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -This will completely replace the default property configuration, so in the above example, the default `opacity utilities` will not be generated. - -Any properties you do not provide will be inherited from the default theme, so in the example above, the default theme configuration for color, spacing, border rounding, background position, etc. will be retained. - -### Extending the default configuration - -If you want to keep the default values of the theme options but add new values, add the extensions under the `designSystem.extend` property. - -For example, if you want to add an additional breakpoint but keep the existing one, you can extend the `screens` property with. - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - extend: { - // Adds a new breakpoint in addition to the default breakpoints - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -You can certainly override some parts of the default theme and extend other parts of the default theme in the same configuration: the - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, - extend: { - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -### Referencing other values - -If you need to reference another value in the configuration, you can do so by providing a closure function instead of a static value. The function will receive the `theme()` function as an argument, and you can use this function to find other values in the configuration using a dot representation. - -For example, you can generate `fill` utilities for each color in the palette by referring to `theme('colors')` on the `fill` configuration. - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - colors: { - // ... - }, - fill: theme => theme('colors'), -}; - -export default defineConfig({ - designSystem, -}); -``` - -The `theme()` function tries to find the value you are looking for from an already fully merged configuration object, so it can reference your own custom settings as well as the default theme value. It also works recursively, so as long as there is a static value at the end of the chain, it can resolve the value you are looking for. - -**Reference to the default configuration** - -If for any reason you want to reference a value in the default configuration, you can import it from `tailwindcss/defaultTheme`. A useful example would be to add one of the fonts provided by the default configuration to. - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const defaultTheme = require('tailwindcss/defaultTheme'); - -const designSystem = { - extend: { - fontFamily: { - sans: ['Lato', ... .defaultTheme.fontFamily.sans], - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -### Disabling the entire core plugin - -If you don't want to generate any classes for a core plugin, it's better to set the plugin to `false` in the `corePlugins` configuration, rather than providing an empty object for the property in the configuration: `` - -```js -// Don't assign an empty object in your theme configuration - -const designSystem = { - opacity: {}, -}; - -// Do disable the plugin in your corePlugins configuration -const designSyttem = { - corePlugins: { - opacity: { false, - }, -}; -``` - -The end result is the same, but since many core plugins don't expose any configuration, it's best to keep it consistent by only disabling them with corePlugins anyway. - -### Adding your own key - -In many cases it may be useful to add your own properties to the configuration object. - -One example is to add new properties for multiplexing between multiple core plugins. For example, you can extract a `positions` object that both the `backgroundPosition` and `objectPosition` plugins can refer to. - -```js -const designSystem = { - positions: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundPosition: theme => theme('positions'), - objectPosition: theme => theme('positions'), -}; -``` - -Another example is to add a new property to a custom plugin for referencing. For example, if you write a gradient plugin for your project, you can add a gradient property to the theme object referenced by that plugin. - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - gradients: theme => ({ - 'blue-green': [theme('colors.blue.500'), theme('colors.green.500')], - 'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')], - // ... - }), -}; - -export default defineConfig({ - designSystem, - buildConfig: { - style: { - postcss: { - plugins: [require('. /plugins/gradients')], - }, - }, - }, -}); -``` - -## Configuration references - -All properties in the configuration object, except `screens`, `colors` and `spacing`, are mapped to the core plugins of `Tailwind CSS`. Since many plugins are responsible for CSS properties that accept only static sets of values (e.g., e.g., `float`), please note that not every plugin has a corresponding property in the theme object. - -All of these properties can also be used under the `designSystem.extend` property to extend the default theme. - -For more information about what all the properties do, check out this [link](https://tailwindcss.com/docs/theme#configuration-reference). diff --git a/packages/document/module-doc/docs/en/guide/advance/theme-config.mdx b/packages/document/module-doc/docs/en/guide/advance/theme-config.mdx deleted file mode 100644 index eacc9adb5543..000000000000 --- a/packages/document/module-doc/docs/en/guide/advance/theme-config.mdx +++ /dev/null @@ -1,60 +0,0 @@ -# Theme Configuration - -Module Tools provides the ability to configure the Tailwind CSS theme through the `designSystem` option. - -## Motivation and Principles - -Theme configuration is similar to custom theme functionality in component libraries and is primarily used for styling. When using `designSystem`, it serves as the `theme` configuration for Tailwind CSS. Therefore, you can use: - -- CSS class names supported by Tailwind CSS. -- Strings with the same name as the CSS class names supported by Tailwind CSS, using the `@apply` custom directive in CSS/Less/Sass. - -For the default value of `designSystem`, refer to the [`designSystem` API](/api/config/design-system). - -## Usage Example - -When using Tailwind CSS, you can use `designSystem` to configure its [`theme`](https://tailwindcss.com/docs/theme). - -For example, the following configuration extends the existing color configuration: - -```ts title="modern.config.ts" -export default { - designSystem: { - extend: { - colors: { - primary: '#1677ff', - }, - }, - }, -}; -``` - -In the code, there are two ways to use Tailwind CSS. - -#### CSS Class Names - -```tsx title="./src/index.tsx" -import 'tailwindcss/utilities.css'; - -export default () => { - return
; -}; -``` - -#### `@apply` Directive - -Regarding [`@apply`](https://tailwindcss.com/docs/functions-and-directives#apply). - -```tsx title="./src/index.tsx" -import './index.css'; - -export default () => { - return
; -}; -``` - -```css title="./src/index.css" -.btn-primary { - @apply bg-primary; -} -``` diff --git a/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx b/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx index 43ff47aaaccb..71d500e12fea 100644 --- a/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx +++ b/packages/document/module-doc/docs/en/guide/best-practices/use-tailwindcss.mdx @@ -258,3 +258,32 @@ var src_default = () => { }; export { src_default as default }; ``` + +### About `designSystem` config + +`designSystem` is a deprecated configuration option in Module Tools. + +Starting from Module Tools vMAJOR_VERSION.33.0, you can use the `theme` configuration option of Tailwind CSS as a replacement for `designSystem`. It is no longer necessary to split the `theme` configuration and set it on `designSystem`. + +- Previous usage: + +```ts title="modern.config.ts" +const { theme, ...rest } = tailwindConfig; + +export default { + style: { + tailwindcss: rest, + }, + designSystem: theme, +}; +``` + +- Current usage: + +```ts title="modern.config.ts" +export default { + style: { + tailwindcss: tailwindConfig, + }, +}; +``` diff --git a/packages/document/module-doc/docs/en/plugins/guide/setup-function.mdx b/packages/document/module-doc/docs/en/plugins/guide/setup-function.mdx index 82f4c607ac1e..51c3ff56f825 100644 --- a/packages/document/module-doc/docs/en/plugins/guide/setup-function.mdx +++ b/packages/document/module-doc/docs/en/plugins/guide/setup-function.mdx @@ -63,7 +63,6 @@ const useResolvedConfigContext: () => NormalizedConfig; interface NormalizedConfig { buildConfig: PartialBuildConfig; buildPreset: BuildPreset; - designSystem?: Record; dev: Dev; plugins: PluginConfig; runtime: RuntimeConfig; diff --git a/packages/document/module-doc/docs/zh/api/config/build-config.mdx b/packages/document/module-doc/docs/zh/api/config/build-config.mdx index 9b07a3b55974..99f4118e7584 100644 --- a/packages/document/module-doc/docs/zh/api/config/build-config.mdx +++ b/packages/document/module-doc/docs/zh/api/config/build-config.mdx @@ -1111,7 +1111,7 @@ const tailwind = { 注意: - 如果你同时使用了 `tailwind.config.{ts,js}` 文件和 `tools.tailwindcss` 选项,那么 `tools.tailwindcss` 定义的配置会优先生效,并覆盖 `tailwind.config.{ts,js}` 中定义的内容。 -- 如果你同时使用了 [designSystem](/api/config/design-system) 配置项,那么 Tailwind CSS 的 `theme` 配置将会被 `designSystem` 的值所覆盖。 +- 如果你同时使用了 `designSystem` 配置项,那么 Tailwind CSS 的 `theme` 配置将会被 `designSystem` 的值所覆盖。 其他配置的使用方式与 Tailwind CSS 官方用法一致,请参考 [tailwindcss - Configuration](https://tailwindcss.com/docs/configuration)。 @@ -1186,7 +1186,7 @@ export default defineConfig({ 比如: -``` ts title="input.js" +```ts title="input.js" import _ from 'lodash'; import { add } from 'lodash/fp'; diff --git a/packages/document/module-doc/docs/zh/api/config/design-system.md b/packages/document/module-doc/docs/zh/api/config/design-system.md deleted file mode 100644 index 49225f555391..000000000000 --- a/packages/document/module-doc/docs/zh/api/config/design-system.md +++ /dev/null @@ -1,1166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# designSystem - -本章描述了有关 designSystem 相关的配置。 - -:::tip -需要先通过 `pnpm run new` 启用 Tailwind CSS 功能。 -::: - -- 类型:`object` -- 默认值: `见下方配置详情`。 - -
- designSystem 配置详情 - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, - colors: { - transparent: 'transparent', - current: 'currentColor', - - black: '#000', - white: '#fff', - - gray: { - 100: '#f7fafc', - 200: '#edf2f7', - 300: '#e2e8f0', - 400: '#cbd5e0', - 500: '#a0aec0', - 600: '#718096', - 700: '#4a5568', - 800: '#2d3748', - 900: '#1a202c', - }, - red: { - 100: '#fff5f5', - 200: '#fed7d7', - 300: '#feb2b2', - 400: '#fc8181', - 500: '#f56565', - 600: '#e53e3e', - 700: '#c53030', - 800: '#9b2c2c', - 900: '#742a2a', - }, - orange: { - 100: '#fffaf0', - 200: '#feebc8', - 300: '#fbd38d', - 400: '#f6ad55', - 500: '#ed8936', - 600: '#dd6b20', - 700: '#c05621', - 800: '#9c4221', - 900: '#7b341e', - }, - yellow: { - 100: '#fffff0', - 200: '#fefcbf', - 300: '#faf089', - 400: '#f6e05e', - 500: '#ecc94b', - 600: '#d69e2e', - 700: '#b7791f', - 800: '#975a16', - 900: '#744210', - }, - green: { - 100: '#f0fff4', - 200: '#c6f6d5', - 300: '#9ae6b4', - 400: '#68d391', - 500: '#48bb78', - 600: '#38a169', - 700: '#2f855a', - 800: '#276749', - 900: '#22543d', - }, - teal: { - 100: '#e6fffa', - 200: '#b2f5ea', - 300: '#81e6d9', - 400: '#4fd1c5', - 500: '#38b2ac', - 600: '#319795', - 700: '#2c7a7b', - 800: '#285e61', - 900: '#234e52', - }, - blue: { - 100: '#ebf8ff', - 200: '#bee3f8', - 300: '#90cdf4', - 400: '#63b3ed', - 500: '#4299e1', - 600: '#3182ce', - 700: '#2b6cb0', - 800: '#2c5282', - 900: '#2a4365', - }, - indigo: { - 100: '#ebf4ff', - 200: '#c3dafe', - 300: '#a3bffa', - 400: '#7f9cf5', - 500: '#667eea', - 600: '#5a67d8', - 700: '#4c51bf', - 800: '#434190', - 900: '#3c366b', - }, - purple: { - 100: '#faf5ff', - 200: '#e9d8fd', - 300: '#d6bcfa', - 400: '#b794f4', - 500: '#9f7aea', - 600: '#805ad5', - 700: '#6b46c1', - 800: '#553c9a', - 900: '#44337a', - }, - pink: { - 100: '#fff5f7', - 200: '#fed7e2', - 300: '#fbb6ce', - 400: '#f687b3', - 500: '#ed64a6', - 600: '#d53f8c', - 700: '#b83280', - 800: '#97266d', - 900: '#702459', - }, - }, - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, - backgroundColor: theme => theme('colors'), - backgroundOpacity: theme => theme('opacity'), - backgroundPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundSize: { - auto: 'auto', - cover: 'cover', - contain: 'contain', - }, - borderColor: theme => ({ - ...theme('colors'), - default: theme('colors.gray.300', 'currentColor'), - }), - borderOpacity: theme => theme('opacity'), - borderRadius: { - none: '0', - sm: '0.125rem', - default: '0.25rem', - md: '0.375rem', - lg: '0.5rem', - full: '9999px', - }, - borderWidth: { - default: '1px', - 0: '0', - 2: '2px', - 4: '4px', - 8: '8px', - }, - boxShadow: { - xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', - sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', - default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', - md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', - lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', - xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', - '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', - inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', - outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', - none: 'none', - }, - container: {}, - cursor: { - auto: 'auto', - default: 'default', - pointer: 'pointer', - wait: 'wait', - text: 'text', - move: 'move', - 'not-allowed': 'not-allowed', - }, - divideColor: theme => theme('borderColor'), - divideOpacity: theme => theme('borderOpacity'), - divideWidth: theme => theme('borderWidth'), - fill: { - current: 'currentColor', - }, - flex: { - 1: '1 1 0%', - auto: '1 1 auto', - initial: '0 1 auto', - none: 'none', - }, - flexGrow: { - 0: '0', - default: '1', - }, - flexShrink: { - 0: '0', - default: '1', - }, - fontFamily: { - sans: [ - 'system-ui', - '-apple-system', - 'BlinkMacSystemFont', - '"Segoe UI"', - 'Roboto', - '"Helvetica Neue"', - 'Arial', - '"Noto Sans"', - 'sans-serif', - '"Apple Color Emoji"', - '"Segoe UI Emoji"', - '"Segoe UI Symbol"', - '"Noto Color Emoji"', - ], - serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], - mono: [ - 'Menlo', - 'Monaco', - 'Consolas', - '"Liberation Mono"', - '"Courier New"', - 'monospace', - ], - }, - fontSize: { - xs: '0.75rem', - sm: '0.875rem', - base: '1rem', - lg: '1.125rem', - xl: '1.25rem', - '2xl': '1.5rem', - '3xl': '1.875rem', - '4xl': '2.25rem', - '5xl': '3rem', - '6xl': '4rem', - }, - fontWeight: { - hairline: '100', - thin: '200', - light: '300', - normal: '400', - medium: '500', - semibold: '600', - bold: '700', - extrabold: '800', - black: '900', - }, - height: theme => ({ - auto: 'auto', - ...theme('spacing'), - full: '100%', - screen: '100vh', - }), - inset: { - 0: '0', - auto: 'auto', - }, - letterSpacing: { - tighter: '-0.05em', - tight: '-0.025em', - normal: '0', - wide: '0.025em', - wider: '0.05em', - widest: '0.1em', - }, - lineHeight: { - none: '1', - tight: '1.25', - snug: '1.375', - normal: '1.5', - relaxed: '1.625', - loose: '2', - 3: '.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 7: '1.75rem', - 8: '2rem', - 9: '2.25rem', - 10: '2.5rem', - }, - listStyleType: { - none: 'none', - disc: 'disc', - decimal: 'decimal', - }, - margin: (theme, { negative }) => ({ - auto: 'auto', - ...theme('spacing'), - ...negative(theme('spacing')), - }), - maxHeight: { - full: '100%', - screen: '100vh', - }, - maxWidth: (theme, { breakpoints }) => ({ - none: 'none', - xs: '20rem', - sm: '24rem', - md: '28rem', - lg: '32rem', - xl: '36rem', - '2xl': '42rem', - '3xl': '48rem', - '4xl': '56rem', - '5xl': '64rem', - '6xl': '72rem', - full: '100%', - ...breakpoints(theme('screens')), - }), - minHeight: { - 0: '0', - full: '100%', - screen: '100vh', - }, - minWidth: { - 0: '0', - full: '100%', - }, - objectPosition: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - opacity: { - 0: '0', - 25: '0.25', - 50: '0.5', - 75: '0.75', - 100: '1', - }, - order: { - first: '-9999', - last: '9999', - none: '0', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - }, - padding: theme => theme('spacing'), - placeholderColor: theme => theme('colors'), - placeholderOpacity: theme => theme('opacity'), - space: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - }), - stroke: { - current: 'currentColor', - }, - strokeWidth: { - 0: '0', - 1: '1', - 2: '2', - }, - textColor: theme => theme('colors'), - textOpacity: theme => theme('opacity'), - width: theme => ({ - auto: 'auto', - ...theme('spacing'), - '1/2': '50%', - '1/3': '33.333333%', - '2/3': '66.666667%', - '1/4': '25%', - '2/4': '50%', - '3/4': '75%', - '1/5': '20%', - '2/5': '40%', - '3/5': '60%', - '4/5': '80%', - '1/6': '16.666667%', - '2/6': '33.333333%', - '3/6': '50%', - '4/6': '66.666667%', - '5/6': '83.333333%', - '1/12': '8.333333%', - '2/12': '16.666667%', - '3/12': '25%', - '4/12': '33.333333%', - '5/12': '41.666667%', - '6/12': '50%', - '7/12': '58.333333%', - '8/12': '66.666667%', - '9/12': '75%', - '10/12': '83.333333%', - '11/12': '91.666667%', - full: '100%', - screen: '100vw', - }), - zIndex: { - auto: 'auto', - 0: '0', - 10: '10', - 20: '20', - 30: '30', - 40: '40', - 50: '50', - }, - gap: theme => theme('spacing'), - gridTemplateColumns: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - 7: 'repeat(7, minmax(0, 1fr))', - 8: 'repeat(8, minmax(0, 1fr))', - 9: 'repeat(9, minmax(0, 1fr))', - 10: 'repeat(10, minmax(0, 1fr))', - 11: 'repeat(11, minmax(0, 1fr))', - 12: 'repeat(12, minmax(0, 1fr))', - }, - gridColumn: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - 'span-7': 'span 7 / span 7', - 'span-8': 'span 8 / span 8', - 'span-9': 'span 9 / span 9', - 'span-10': 'span 10 / span 10', - 'span-11': 'span 11 / span 11', - 'span-12': 'span 12 / span 12', - }, - gridColumnStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridColumnEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - 8: '8', - 9: '9', - 10: '10', - 11: '11', - 12: '12', - 13: '13', - }, - gridTemplateRows: { - none: 'none', - 1: 'repeat(1, minmax(0, 1fr))', - 2: 'repeat(2, minmax(0, 1fr))', - 3: 'repeat(3, minmax(0, 1fr))', - 4: 'repeat(4, minmax(0, 1fr))', - 5: 'repeat(5, minmax(0, 1fr))', - 6: 'repeat(6, minmax(0, 1fr))', - }, - gridRow: { - auto: 'auto', - 'span-1': 'span 1 / span 1', - 'span-2': 'span 2 / span 2', - 'span-3': 'span 3 / span 3', - 'span-4': 'span 4 / span 4', - 'span-5': 'span 5 / span 5', - 'span-6': 'span 6 / span 6', - }, - gridRowStart: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - gridRowEnd: { - auto: 'auto', - 1: '1', - 2: '2', - 3: '3', - 4: '4', - 5: '5', - 6: '6', - 7: '7', - }, - transformOrigin: { - center: 'center', - top: 'top', - 'top-right': 'top right', - right: 'right', - 'bottom-right': 'bottom right', - bottom: 'bottom', - 'bottom-left': 'bottom left', - left: 'left', - 'top-left': 'top left', - }, - scale: { - 0: '0', - 50: '.5', - 75: '.75', - 90: '.9', - 95: '.95', - 100: '1', - 105: '1.05', - 110: '1.1', - 125: '1.25', - 150: '1.5', - }, - rotate: { - '-180': '-180deg', - '-90': '-90deg', - '-45': '-45deg', - 0: '0', - 45: '45deg', - 90: '90deg', - 180: '180deg', - }, - translate: (theme, { negative }) => ({ - ...theme('spacing'), - ...negative(theme('spacing')), - '-full': '-100%', - '-1/2': '-50%', - '1/2': '50%', - full: '100%', - }), - skew: { - '-12': '-12deg', - '-6': '-6deg', - '-3': '-3deg', - 0: '0', - 3: '3deg', - 6: '6deg', - 12: '12deg', - }, - transitionProperty: { - none: 'none', - all: 'all', - default: - 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', - colors: 'background-color, border-color, color, fill, stroke', - opacity: 'opacity', - shadow: 'box-shadow', - transform: 'transform', - }, - transitionTimingFunction: { - linear: 'linear', - in: 'cubic-bezier(0.4, 0, 1, 1)', - out: 'cubic-bezier(0, 0, 0.2, 1)', - 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', - }, - transitionDuration: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, - transitionDelay: { - 75: '75ms', - 100: '100ms', - 150: '150ms', - 200: '200ms', - 300: '300ms', - 500: '500ms', - 700: '700ms', - 1000: '1000ms', - }, -}; -``` - -:::tip -更多关于[Tailwind CSS 配置](https://tailwindcss.com/docs/configuration#theme) -::: - -
- -`designSystem` 用于定义项目的调色板、排版比例(Typographic Scales 或者 Type Scale)、字体列表、断点、边框圆角值等等。因为 Modern.js 借用了 Tailwind Theme 的设计方式,并且内部也集成了 Tailwind CSS,所以 `designSystem` 使用方式与 Tailwind CSS Theme 相同 - -`designSystem` 对象包含 `screens`、`colors` 和 `spacing` 的属性,以及每个可自定义核心插件。 - -## Screens - -使用`screens` 可以自定义项目中的响应断点: - -```js -const designSystem = { - screens: { - sm: '640px', - md: '768px', - lg: '1024px', - xl: '1280px', - }, -}; -``` - -其中 `screens` 对象里的属性名是屏幕名称(用作 `Tailwind CSS` 生成的自适应实用程序变体的前缀,例如 `md:text-center`),值是该断点应在其开始的 `min-width`。 - -默认断点受常见设备分辨率的启发: - -```js -const designSystem = { - screens: { - sm: '640px', - // => @media (min-width: 640px) { ... } - - md: '768px', - // => @media (min-width: 768px) { ... } - - lg: '1024px', - // => @media (min-width: 1024px) { ... } - - xl: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -你可以在你的项目中使用任意你喜欢的名称作为断点的属性: - -```js -const designSystem = { - screens: { - tablet: '640px', - // => @media (min-width: 640px) { ... } - - laptop: '1024px', - // => @media (min-width: 1024px) { ... } - - desktop: '1280px', - // => @media (min-width: 1280px) { ... } - }, -}; -``` - -这些屏幕名称反映在 `utilities` 中,因此 `text-center` 现在是这样的: - -```css -.text-center { - text-align: center; -} - -@media (min-width: 640px) { - .tablet\:text-center { - text-align: center; - } -} - -@media (min-width: 1024px) { - .laptop\:text-center { - text-align: center; - } -} - -@media (min-width: 1280px) { - .desktop\:text-center { - text-align: center; - } -} -``` - -### Max-width 断点 - -如果要使用 `max-width` 断点而不是 `min-width`,可以将屏幕指定为具有 `max` 属性的对象: - -```js -const designSystem = { - screens: { - xl: { max: '1279px' }, - // => @media (max-width: 1279px) { ... } - - lg: { max: '1023px' }, - // => @media (max-width: 1023px) { ... } - - md: { max: '767px' }, - // => @media (max-width: 767px) { ... } - - sm: { max: '639px' }, - // => @media (max-width: 639px) { ... } - }, -}; -``` - -如有必要,以创建带有 `min-width` 和 `max-width` 定义的断点,例如: - -```js -const designSystem = { - screens: { - sm: { min: '640px', max: '767px' }, - md: { min: '768px', max: '1023px' }, - lg: { min: '1024px', max: '1279px' }, - xl: { min: '1280px' }, - }, -}; -``` - -### 多个范围的断点 - -有时,将单个断点定义应用于多个范围会很有用。 - -例如,假设您有一个 `sidebar`,并且希望断点基于内容区域宽度而不是整个视口。您可以模拟这种情况,当 `sidebar` 可见并缩小内容区域时,断点的样式使用较小的断点样式: - -```js -const designSystem = { - screens: { - sm: '500px', - md: [ - // Sidebar appears at 768px, so revert to `sm:` styles between 768px - // and 868px, after which the main content area is wide enough again to - // apply the `md:` styles. - { min: '668px', max: '767px' }, - { min: '868px' }, - ], - lg: '1100px', - xl: '1400px', - }, -}; -``` - -### 自定义媒体查询 - -如果需要为断点提供完全自定义的媒体查询,则可以使用带有 `raw` 属性的对象: - -```js -const designSystem = { - extend: { - screens: { - portrait: { raw: '(orientation: portrait)' }, - // => @media (orientation: portrait) { ... } - }, - }, -}; -``` - -### Print 样式 - -如果需要为打印应用不同的样式,则 `raw` 选项可能特别有用。 - -需要做的就是在 `designSystem.extend.screens` 下添加一个 `print`: - -```js -const designSystem = { - extend: { - screens: { - print: { raw: 'print' }, - // => @media print { ... } - }, - }, -}; -``` - -然后,可以使用诸如 `print:text-black` 之类的类来指定仅当某人尝试打印页面时才应用的样式: - -```html -
- -
-``` - -### Dark Mode - -`raw` 选项可以用于实现 “暗模式” 屏幕: - -```js -const designSystem = { - extend: { - screens: { - dark: { raw: '(prefers-color-scheme: dark)' }, - // => @media (prefers-color-scheme: dark) { ... } - }, - }, -}; -``` - -然后,您可以使用 `dark:` 前缀在暗模式下为元素设置不同的样式: - -```html -
- -
-``` - -请注意,由于这些 `screen variants` 是在 `Tailwind CSS` 中实现的,因此**无法使用这种方法将断点与暗模式结合使用** ,例如 `md:dark:text-gray-300` 将不起作用。 - -## Colors - -`colors` 属性可让您自定义项目的全局调色板。 - -```js -const designSystem = { - colors: { - transparent: 'transparent', - black: '#000', - white: '#fff', - gray: { - 100: '#f7fafc', - // ... - 900: '#1a202c', - }, - - // ... - }, -}; -``` - -默认情况下,这些颜色由 `backgroundColor`,`textColor` 和 `borderColor` 核心插件继承。 - -想了解更多,可以查看:[Customizing Colors](https://tailwindcss.com/docs/customizing-colors)。 - -## Spacing - -使用 `space` 属性,可以自定义项目的全局间距和缩放比例: - -```js -const designSystem = { - spacing: { - px: '1px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 6: '1.5rem', - 8: '2rem', - 10: '2.5rem', - 12: '3rem', - 16: '4rem', - 20: '5rem', - 24: '6rem', - 32: '8rem', - 40: '10rem', - 48: '12rem', - 56: '14rem', - 64: '16rem', - }, -}; -``` - -默认情况下,这些值由 `padding`,`margin`,`negativeMargin`,`width` 和 `height` 核心插件继承。 - -想要了解更多,看 [Customizing Spacing](https://tailwindcss.com/docs/customizing-spacing)。 - -## 核心插件 - -主题部分的其余部分用于配置每个核心插件可用的值。 - -例如,`borderRadius` 属性可让您自定义将生成的圆角的 `utilities`: - -```js -const designSystem = { - borderRadius: { - none: '0', - sm: '.125rem', - default: '.25rem', - lg: '.5rem', - full: '9999px', - }, -}; -``` - -**属性名确定所生成类的后缀,值确定实际 CSS 声明的值。** -上面的示例`borderRadius`配置将生成以下 CSS 类: - -```css -.rounded-none { - border-radius: 0; -} -.rounded-sm { - border-radius: 0.125rem; -} -.rounded { - border-radius: 0.25rem; -} -.rounded-lg { - border-radius: 0.5rem; -} -.rounded-full { - border-radius: 9999px; -} -``` - -会注意到,在主题配置中使用 `default` 属性创建了不带后缀的 `rounded` 类。这是许多(尽管不是全部)核心插件支持的 Tailwind CSS 中的通用约定。 - -要了解有关自定义特定核心插件的更多信息,请访问该插件的文档。 - -## 自定义默认配置 - -开箱即用,您的项目将自动从默认主题配置继承值。如果想自定义默认主题,则根据目标有几种不同的选择。 - -### 覆盖默认配置 - -要覆盖默认配置中的选项,请在 `designSystem` 中添加要覆盖的属性: - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - // Replaces all of the default `opacity` values - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -这将完全替换默认属性配置,因此在上面的示例中,不会生成默认的 `opacity utilities`。 - -您未提供的任何属性都将从默认主题继承,因此在上面的示例中,将保留颜色,间距,边框圆角,背景位置等内容的默认主题配置。 - -### 扩展默认配置 - -如果您想保留主题选项的默认值,但又要添加新值,请在 `designSystem.extend` 属性下添加扩展的内容。 - -例如,如果您想添加一个额外的断点但保留现有的断点,则可以扩展 `screens` 属性: - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - extend: { - // Adds a new breakpoint in addition to the default breakpoints - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -您当然可以覆盖默认主题的某些部分,并在同一配置中扩展默认主题的其他部分: - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - opacity: { - 0: '0', - 20: '0.2', - 40: '0.4', - 60: '0.6', - 80: '0.8', - 100: '1', - }, - extend: { - screens: { - '2xl': '1440px', - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -### 引用其他值 - -如果需要在配置中引用另一个值,可以通过提供闭包函数而不是静态值来实现。函数将收到 `theme()` 函数作为参数,您可以使用该函数使用点表示法在配置中查找其他值。 - -例如,您可以在 `fill` 配置上通过引用 `theme('colors')` 为调色板中的每种颜色生成 `fill` utilities。 - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - colors: { - // ... - }, - fill: theme => theme('colors'), -}; - -export default defineConfig({ - designSystem, -}); -``` - -`theme()`函数尝试从已经完全合并的配置对象中找到您要查找的值,因此它可以引用您自己的自定义设置以及默认主题值。它也可以递归工作,因此只要链末尾有一个静态值,它就可以解析您要查找的值。 - -**引用默认配置** - -如果出于任何原因想要引用默认配置中的值,则可以从 `tailwindcss/defaultTheme` 导入它。一个有用的示例是,如果要将添加默认配置提供的字体中某一个字体: - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const defaultTheme = require('tailwindcss/defaultTheme'); - -const designSystem = { - extend: { - fontFamily: { - sans: ['Lato', ...defaultTheme.fontFamily.sans], - }, - }, -}; - -export default defineConfig({ - designSystem, -}); -``` - -### 禁用整个核心插件 - -如果您不想为某个核心插件生成任何类,则最好在 `corePlugins` 配置中将该插件设置为 `false`,而不是在配置中为该属性提供一个空对象: - -```js -// Don't assign an empty object in your theme configuration - -const designSystem = { - opacity: {}, -}; - -// Do disable the plugin in your corePlugins configuration -const designSyttem = { - corePlugins: { - opacity: false, - }, -}; -``` - -最终结果是相同的,但是由于许多核心插件未公开任何配置,因此无论如何只能使用 corePlugins 禁用它们,最好保持一致。 - -### 添加自己的 key - -在很多情况下,将自己的属性添加到配置对象可能会很有用。 - -其中一个示例是添加新属性为多个核心插件之间复用。例如,您可以提取一个 `positions`对象,`backgroundPosition` 和 `objectPosition` 插件都可以引用该对象: - -```js -const designSystem = { - positions: { - bottom: 'bottom', - center: 'center', - left: 'left', - 'left-bottom': 'left bottom', - 'left-top': 'left top', - right: 'right', - 'right-bottom': 'right bottom', - 'right-top': 'right top', - top: 'top', - }, - backgroundPosition: theme => theme('positions'), - objectPosition: theme => theme('positions'), -}; -``` - -另一个示例是在自定义插件中添加新的属性以进行引用。例如,如果您为项目编写了渐变插件,则可以向该插件引用的主题对象添加渐变属性: - -```js title="modern.config.ts" -import { defineConfig } from '@modern-js/module-tools'; - -const designSystem = { - gradients: theme => ({ - 'blue-green': [theme('colors.blue.500'), theme('colors.green.500')], - 'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')], - // ... - }), -}; - -export default defineConfig({ - designSystem, - buildConfig: { - style: { - postcss: { - plugins: [require('./plugins/gradients')], - }, - }, - }, -}); -``` - -## 配置引用 - -除了 `screens`,`colors` 和 `spacing` 外,配置对象中的所有属性都映射到 `Tailwind CSS` 的核心插件上。由于许多插件负责仅接受静态值集(例如,例如`float`)的 CSS 属性,因此请注意,并非每个插件在主题对象中都有对应的属性。 - -所有这些属性也可以在 `designSystem.extend` 属性下使用,以扩展默认主题。 - -关于所有属性的作用,可以查看此 [链接](https://tailwindcss.com/docs/theme#configuration-reference)。 diff --git a/packages/document/module-doc/docs/zh/guide/advance/theme-config.mdx b/packages/document/module-doc/docs/zh/guide/advance/theme-config.mdx deleted file mode 100644 index 8ed40a3e30c3..000000000000 --- a/packages/document/module-doc/docs/zh/guide/advance/theme-config.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -sidebar_position: 6 ---- - -# 主题配置 - -Module Tools 通过 [`designSystem`](/api/config/design-system) 选项,提供了配置 Tailwind CSS 主题的能力。 - -## 动机和原理 - -主题配置有些类似组件库中的定制主题功能,主要用于开发样式。当你使用 `designSystem` 时,它会作为 Tailwind CSS 的 `theme` 配置。因此你可以使用: - -- Tailwind CSS 支持的 CSS 类名。 -- 在 CSS/Less/Sass 下通过 `@apply` 自定义指令使用与 Tailwind CSS 支持的 CSS 类名同名的字符串。 - -关于 `designSystem` 的默认值,可以查看 [`designSystem` API](/api/config/design-system)。 - -## 使用示例 - -在使用 Tailwind CSS 的时候,可以通过 `designSystem` 来设置它的 [`theme`](https://tailwindcss.com/docs/theme) 配置。 - -例如在下面的配置中扩展了原有的颜色配置: - -```ts title="modern.config.ts" -export default { - designSystem: { - extend: { - colors: { - primary: '#1677ff', - }, - }, - }, -}; -``` - -在代码中,我们可以有两种使用 Tailwind CSS 的方式。 - -#### CSS 类名 - -```tsx title="./src/index.tsx" -import 'tailwindcss/utilities.css'; - -export default () => { - return
; -}; -``` - -#### `@apply` 指令 - -关于 [`@apply`](https://tailwindcss.com/docs/functions-and-directives#apply)。 - -```tsx title="./src/index.tsx" -import './index.css'; - -export default () => { - return
; -}; -``` - -```css title="./src/index.css" -.btn-primary { - @apply bg-primary; -} -``` diff --git a/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx b/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx index f2ba99ac89bc..20ba1f7c4bc0 100644 --- a/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx +++ b/packages/document/module-doc/docs/zh/guide/best-practices/use-tailwindcss.mdx @@ -258,3 +258,32 @@ var src_default = () => { }; export { src_default as default }; ``` + +### 关于 `designSystem` 配置 + +`designSystem` 是 Module Tools 中废弃的配置项。 + +从 Module Tools vMAJOR_VERSION.33.0 版本开始,你可以使用 Tailwind CSS 的 `theme` 配置项来代替 `designSystem`,不再需要将 `theme` 配置拆分并设置到 `designSystem` 上。 + +- 旧版本用法: + +```ts title="modern.config.ts" +const { theme, ...rest } = tailwindConfig; + +export default { + style: { + tailwindcss: rest, + }, + designSystem: theme, +}; +``` + +- 当前版本用法: + +```ts title="modern.config.ts" +export default { + style: { + tailwindcss: tailwindConfig, + }, +}; +``` diff --git a/packages/document/module-doc/docs/zh/plugins/guide/setup-function.mdx b/packages/document/module-doc/docs/zh/plugins/guide/setup-function.mdx index 828fc3c2237d..e8e28e3ddbf0 100644 --- a/packages/document/module-doc/docs/zh/plugins/guide/setup-function.mdx +++ b/packages/document/module-doc/docs/zh/plugins/guide/setup-function.mdx @@ -63,7 +63,6 @@ const useResolvedConfigContext: () => NormalizedConfig; interface NormalizedConfig { buildConfig: PartialBuildConfig; buildPreset: BuildPreset; - designSystem?: Record; dev: Dev; plugins: PluginConfig; runtime: RuntimeConfig; diff --git a/packages/generator/generators/doc-generator/templates/docs/zh/guide/install.mdx b/packages/generator/generators/doc-generator/templates/docs/zh/guide/install.mdx index 51a205f9a1f0..755b8b6a23e2 100644 --- a/packages/generator/generators/doc-generator/templates/docs/zh/guide/install.mdx +++ b/packages/generator/generators/doc-generator/templates/docs/zh/guide/install.mdx @@ -59,7 +59,6 @@ const useResolvedConfigContext: () => NormalizedConfig; interface NormalizedConfig { buildConfig: PartialBuildConfig; buildPreset: BuildPreset; - designSystem?: Record; dev: Dev; plugins: PluginConfig; runtime: RuntimeConfig; diff --git a/packages/solutions/app-tools/src/types/config/source.ts b/packages/solutions/app-tools/src/types/config/source.ts index 0e98da2c41b7..6b9b72a7ed7a 100644 --- a/packages/solutions/app-tools/src/types/config/source.ts +++ b/packages/solutions/app-tools/src/types/config/source.ts @@ -62,10 +62,8 @@ export interface SharedSourceConfig extends BuilderSharedSourceConfig { */ configDir?: string; /** - * Used to define the project's theme configuration such as color palette. - * @requires `tailwindcss` plugin. - * The configuration of `source.designSystem` is provided by `tailwindcss` plugin. - * Please use `yarn new` or `pnpm new` to enable the corresponding capability. + * @deprecated designSystem is no longer required. + * If you are using Tailwind CSS, you can now use the `theme` option of Tailwind CSS, they are the same. */ designSystem?: Record; } diff --git a/packages/solutions/app-tools/src/types/legacyConfig/source.ts b/packages/solutions/app-tools/src/types/legacyConfig/source.ts index e336ae528077..7afde01b48fe 100644 --- a/packages/solutions/app-tools/src/types/legacyConfig/source.ts +++ b/packages/solutions/app-tools/src/types/legacyConfig/source.ts @@ -31,9 +31,8 @@ export type SourceLegacyUserConfig = { include?: Array; /** - * The configuration of `source.designSystem` is provided by `tailwindcss` plugin. - * Please use `yarn new` or `pnpm new` to enable the corresponding capability. - * @requires `tailwindcss` plugin + * @deprecated designSystem is no longer required. + * If you are using Tailwind CSS, you can now use the `theme` option of Tailwind CSS, they are the same. */ designSystem?: Record; }; diff --git a/packages/solutions/module-tools/src/types/config/index.ts b/packages/solutions/module-tools/src/types/config/index.ts index 77c1631ef68e..f2d1779f4056 100644 --- a/packages/solutions/module-tools/src/types/config/index.ts +++ b/packages/solutions/module-tools/src/types/config/index.ts @@ -167,6 +167,10 @@ export interface RuntimeUserConfig { } export interface ModuleExtraConfig { + /** + * @deprecated designSystem is no longer required. + * If you are using Tailwind CSS, you can now use the `theme` option of Tailwind CSS, they are the same. + */ designSystem?: Record; buildConfig?: PartialBuildConfig; diff --git a/packages/solutions/module-tools/src/types/legacyConfig/source.ts b/packages/solutions/module-tools/src/types/legacyConfig/source.ts index 6194aa24b1ec..3894d3b398bd 100644 --- a/packages/solutions/module-tools/src/types/legacyConfig/source.ts +++ b/packages/solutions/module-tools/src/types/legacyConfig/source.ts @@ -6,9 +6,8 @@ export type SourceLegacyUserConfig = { globalVars?: Record; jsxTransformRuntime?: 'automatic' | 'classic'; /** - * The configuration of `source.designSystem` is provided by `tailwindcss` plugin. - * Please use `yarn new` or `pnpm new` to enable the corresponding capability. - * @requires `tailwindcss` plugin + * @deprecated designSystem is no longer required. + * If you are using Tailwind CSS, you can now use the `theme` option of Tailwind CSS, they are the same. */ designSystem?: Record; }; From bc1f8daf0ff83b3667f398c81f674aab36b80b30 Mon Sep 17 00:00:00 2001 From: yangxingyuan <39261479+sanyuan0704@users.noreply.github.com> Date: Sun, 27 Aug 2023 15:20:25 +0800 Subject: [PATCH 4/4] feat(builder): support custom logger (#4522) * feat: support custom logger * chore: optimzie variable name * feat: add docs --- .changeset/shy-countries-run.md | 12 +++++ .../builder/builder-shared/src/devServer.ts | 9 +++- .../builder/builder-shared/src/prodServer.ts | 8 ++- .../builder-shared/src/types/provider.ts | 3 ++ .../docs/en/api/builder-instance.mdx | 51 +++++++++++++++++- .../docs/zh/api/builder-instance.mdx | 52 ++++++++++++++++++- packages/toolkit/utils/src/cli/port.ts | 4 +- 7 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 .changeset/shy-countries-run.md diff --git a/.changeset/shy-countries-run.md b/.changeset/shy-countries-run.md new file mode 100644 index 000000000000..825174c6a115 --- /dev/null +++ b/.changeset/shy-countries-run.md @@ -0,0 +1,12 @@ +--- +'@modern-js/builder-shared': patch +'@modern-js/plugin-tailwindcss': patch +'@modern-js/module-tools-docs': patch +'@modern-js/main-doc': patch +'@modern-js/utils': patch +'@modern-js/doc-core': patch +--- + +feat(builder): support custom logger in dev server + +feat(builder): 支持自定义 logger diff --git a/packages/builder/builder-shared/src/devServer.ts b/packages/builder/builder-shared/src/devServer.ts index af0e09900af8..c1b1dde1d905 100644 --- a/packages/builder/builder-shared/src/devServer.ts +++ b/packages/builder/builder-shared/src/devServer.ts @@ -9,7 +9,7 @@ import type { } from './types'; import type { ModernDevServerOptions, Server } from '@modern-js/server'; import { merge } from '@modern-js/utils/lodash'; -import { logger, debug } from './logger'; +import { logger as defaultLogger, debug } from './logger'; import { DEFAULT_PORT } from './constants'; import { createAsyncHook } from './createHook'; import { getServerOptions, printServerURLs } from './prodServer'; @@ -95,10 +95,14 @@ export async function startDevServer< printURLs = true, strictPort = false, serverOptions = {}, + logger: customLogger, + getPortSilently, }: StartDevServerOptions & { defaultPort?: number; } = {}, ) { + const logger = customLogger ?? defaultLogger; + logger.info('Starting dev server...'); if (!process.env.NODE_ENV) { @@ -112,6 +116,7 @@ export async function startDevServer< const port = await getPort(builderConfig.dev?.port || DEFAULT_PORT, { strictPort, + slient: getPortSilently, }); const host = @@ -165,7 +170,7 @@ export async function startDevServer< } } - await printServerURLs(urls, 'Dev server'); + await printServerURLs(urls, 'Dev server', logger); } await options.context.hooks.onAfterStartDevServerHook.call({ port }); diff --git a/packages/builder/builder-shared/src/prodServer.ts b/packages/builder/builder-shared/src/prodServer.ts index 132118ba6d19..aa821aa024b1 100644 --- a/packages/builder/builder-shared/src/prodServer.ts +++ b/packages/builder/builder-shared/src/prodServer.ts @@ -1,5 +1,8 @@ -import prodServer, { type ModernServerOptions } from '@modern-js/prod-server'; -import { logger } from './logger'; +import prodServer, { + Logger, + type ModernServerOptions, +} from '@modern-js/prod-server'; +import { logger as defaultLogger } from './logger'; import { DEFAULT_PORT } from './constants'; import type { BuilderContext, @@ -32,6 +35,7 @@ export const getServerOptions = ( export async function printServerURLs( urls: Array<{ url: string; label: string }>, name = 'Server', + logger: Logger = defaultLogger, ) { const { chalk } = await import('@modern-js/utils'); let message = `${name} running at:\n\n`; diff --git a/packages/builder/builder-shared/src/types/provider.ts b/packages/builder/builder-shared/src/types/provider.ts index cf83be80991c..ccc39cfb7f45 100644 --- a/packages/builder/builder-shared/src/types/provider.ts +++ b/packages/builder/builder-shared/src/types/provider.ts @@ -4,6 +4,7 @@ import type { Compiler, MultiCompiler } from 'webpack'; import type { BuilderMode, CreateBuilderOptions } from './builder'; import type { Server, ModernDevServerOptions } from '@modern-js/server'; import type { AddressUrl } from '@modern-js/utils'; +import { Logger } from '@modern-js/prod-server'; export type Bundler = 'webpack' | 'rspack'; @@ -12,7 +13,9 @@ export type CreateCompilerOptions = { watch?: boolean }; export type StartDevServerOptions = { compiler?: Compiler | MultiCompiler; printURLs?: boolean | ((urls: AddressUrl[]) => AddressUrl[]); + logger?: Logger; strictPort?: boolean; + getPortSilently?: boolean; serverOptions?: Partial> & { config?: Partial; }; diff --git a/packages/document/builder-doc/docs/en/api/builder-instance.mdx b/packages/document/builder-doc/docs/en/api/builder-instance.mdx index 89eac186dce7..850d72644203 100644 --- a/packages/document/builder-doc/docs/en/api/builder-instance.mdx +++ b/packages/document/builder-doc/docs/en/api/builder-instance.mdx @@ -199,6 +199,10 @@ type StartDevServerOptions = { compiler?: Compiler | MultiCompiler; // passing through the build-independent dev server configuration serverOptions?: Partial; + // Whether to get the port silently, the default is false + getPortSliently?: boolean; + // custom logger + logger?: Logger; }; type StartServerResult = { @@ -293,6 +297,52 @@ await builder.startDevServer({ }); ``` +### Get Port Silently + +In some cases, the default startup port number is already occupied. In this situation, Builder will automatically increment the port number until it finds an available one. This process will output a prompt log. If you do not want this log, you can set `getPortSliently` to `true`. + +```ts +await builder.startDevServer({ + getPortSliently: true, +}); +``` + +### Custom Logger + +By default, Builder uses `@modern-js/utils/logger` to output logs. You can customize the log output object through the `logger` parameter. + +```ts +const customLogger = { + // You need to define the following methods + info(msg: string) { + console.log(msg); + }, + error(msg: string) { + console.error(msg); + }, + warn(msg: string) { + console.warn(msg); + }, + success(msg: string) { + console.log(`✅ msg`); + }, + debug(msg: string) { + if (process.env.DEBUG) { + console.log(msg); + } + }, + log(msg: string) { + console.log(msg); + }; +} + +await builder.startDevServer({ + logger: customLogger, +}); +``` + +Then Builder will use the custom logger to output logs. + ## builder.serve Start a server to preview the production build locally. This method should be executed after `builder.build`. @@ -332,7 +382,6 @@ console.log(port); // 8080 await server.close(); ``` - ## builder.createCompiler Create a Compiler object. diff --git a/packages/document/builder-doc/docs/zh/api/builder-instance.mdx b/packages/document/builder-doc/docs/zh/api/builder-instance.mdx index e4350cd78c1b..68ee20c9427d 100644 --- a/packages/document/builder-doc/docs/zh/api/builder-instance.mdx +++ b/packages/document/builder-doc/docs/zh/api/builder-instance.mdx @@ -199,6 +199,10 @@ type StartDevServerOptions = { compiler?: Compiler | MultiCompiler; // 透传与构建无关的 dev server 配置 serverOptions?: Partial; + // 是否在启动时静默获取端口号,默认为 false + getPortSliently?: boolean; + // 自定义日志输出对象 + logger?: Logger; }; type StartServerResult = { @@ -293,6 +297,52 @@ await builder.startDevServer({ }); ``` +### 静默获取端口号 + +某些情况下,默认启动的端口号已经被占用,此时 Builder 会自动递增端口号,直至找到一个可用端口。这个过程会输出提示日志,如果你不希望这段日志,可以将 `getPortSliently` 设置为 `true`。 + +```ts +await builder.startDevServer({ + getPortSliently: true, +}); +``` + +### 自定义日志输出对象 + +默认情况下,Builder 会使用 `@modern-js/utils/logger` 来输出日志,你可以通过 `logger` 参数来自定义日志输出对象。 + +```ts +const customLogger = { + // 你需要定义以下的方法 + info(msg: string) { + console.log(msg); + }, + error(msg: string) { + console.error(msg); + }, + warn(msg: string) { + console.warn(msg); + }, + success(msg: string) { + console.log(`✅ msg`); + }, + debug(msg: string) { + if (process.env.DEBUG) { + console.log(msg); + } + }, + log(msg: string) { + console.log(msg); + }; +} + +await builder.startDevServer({ + logger: customLogger, +}); +``` + +这样,Builder 会使用你自定义的日志输出对象来输出日志。 + ## builder.serve 在本地启动 Server 来预览生产环境构建的产物,需要在 `builder.build` 方法之后执行。 @@ -317,7 +367,6 @@ function server(): Promise; await builder.serve(); ``` - `serve` 会返回以下参数: - `urls`:访问 Server 的 URLs @@ -333,7 +382,6 @@ console.log(port); // 8080 await server.close(); ``` - ## builder.createCompiler 创建一个 compiler 对象。 diff --git a/packages/toolkit/utils/src/cli/port.ts b/packages/toolkit/utils/src/cli/port.ts index bac655717f38..3ae1c87d9763 100644 --- a/packages/toolkit/utils/src/cli/port.ts +++ b/packages/toolkit/utils/src/cli/port.ts @@ -15,9 +15,11 @@ export const getPort = async ( { tryLimits = 20, strictPort = false, + slient = false, }: { tryLimits?: number; strictPort?: boolean; + slient?: boolean; } = {}, ): Promise => { if (typeof port === 'string') { @@ -63,7 +65,7 @@ export const getPort = async ( throw new Error( `Port "${original}" is occupied, please choose another one.`, ); - } else { + } else if (!slient) { logger.info( `Something is already running on port ${original}. ${chalk.yellow( `Use port ${port} instead.`,