buildConfig
buildConfig
是一个用来描述如何编译、生成构建产物的配置项,它包含了构建的所有配置。
TIP
在开始使用 buildConfig
之前,请先阅读以下文档来了解其作用:
alias
- 类型:
Record<string, string> | Function
- 默认值:
{'@': 'src',}
TIP
对于 TypeScript 项目,只需要在 tsconfig.json
中配置 compilerOptions.paths, Modern.js Module 会自动识别 tsconfig.json
里的别名,因此不需要额外配置 alias
字段。
modern.config.ts
export default defineConfig({
buildConfig: {
alias: {
'@common': './src/common',
},
},
});
以上配置完成后,如果在代码中引用 @common/Foo.tsx
, 则会映射到 <project>/src/common/Foo.tsx
路径上。
alias
的值定义为函数时,可以接受预设的 alias 对象,并对其进行修改。
modern.config.ts
export default defineConfig({
buildConfig: {
alias: alias => {
alias['@common'] = './src/common';
},
},
});
也可以在函数中返回一个新对象作为最终结果,新对象会覆盖预设的 alias 对象。
modern.config.ts
export default defineConfig({
buildConfig: {
alias: alias => {
return {
'@common': './src/common',
};
},
},
});
asset
包含静态资源相关的配置。
asset.name
静态资源输出文件名。
- 类型:
string | ((assetPath) => name)
- 默认值:
[name].[hash].[ext]
当 asset.name 为 string 类型时,会自动对 [name]、[ext]、[hash] 进行替换,分别替换为文件名、拓展名、文件 hash。
如果想要更高的自由度,可以把 asset.name 作为方法使用,返回值即为文件名。此时,该方法接收一个参数 assetPath,对应资源路径。
modern.config.ts
export default defineConfig({
buildConfig: {
asset: {
// no hash
name: [name].[ext],
// any logic
// name: (assetPath) => 'any.png',
},
},
});
asset.limit
用于设置静态资源被自动内联为 base64 的体积阈值。
Modern.js Module 在进行打包时,默认会内联体积小于 10KB 的图片、字体、媒体等资源,将它们通过 Base64 编码,并内联到产物中,不再会发送独立的 HTTP 请求。
你可以通过修改 limit
参数来调整这个阈值。
- 类型:
number
- 默认值:
10 * 1024
例如,将 limit
设置为 0
来避免资源内联:
modern.config.ts
export default defineConfig({
buildConfig: {
asset: {
limit: 0,
},
},
});
asset.path
静态资源输出路径,会基于 outDir 进行输出。
asset.publicPath
打包时给未内联资源的 CDN 前缀。
- 类型:
string
- 默认值:
undefined
modern.config.ts
export default defineConfig({
buildConfig: {
asset: {
publicPath: 'https://xxx/',
},
},
});
此时,所有静态资源都会添加 https://xxx/
前缀。
asset.svgr
打包时将 SVG 作为一个 React 组件处理,options 参考 svgr,另外还支持了 include
和 exclude
两个配置项,用于匹配需要处理的 SVG 文件。
- 类型:
boolean | object
- 默认值:
false
开启 svgr 功能后,可以使用默认导出的方式将 SVG 当做组件使用。
index.ts
// true
import Logo from './logo.svg';
export default () => <Logo />;
当开启功能后,可以新建一个类型描述文件,并在 modern-app-env.d.ts
文件中增加,修改使用 SVG 的类型:
your-app-env.d.ts
declare module '*.svg' {
const src: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
export default src;
}
modern-app-env.d.ts
/// <reference path='./your-app-env.d.ts' />
/// <reference types='@modern-js/module-tools/types' />
asset.svgr.include
设定匹配的 SVG 文件
- 类型:
string | RegExp | (string | RegExp)[]
- 默认值:
/\.svg$/
asset.svgr.exclude
设定不匹配的 SVG 文件
- 类型:
string | RegExp | (string | RegExp)[]
- 默认值:
undefined
asset.svgr.exportType
用于配置使用 SVGR 时 SVG 的导出形式。
- 类型:
'named' | 'default'
- 默认值:
default
当此选项设置为 'named' 时,你可以使用以下语法导入组件:
index.ts
import { ReactComponent } from './logo.svg';
命名导出默认为 ReactComponent
,并可以通过 asset.svgr.namedExport
进行自定义。
autoExtension
根据 format 和 type 自动添加产物里 js 文件和类型描述文件的后缀。
- 类型:
boolean
- 默认值:
false
- 版本:
>=2.38.0
关闭时,js 产物后缀为 .js
,类型描述文件后缀为 d.ts
。
开启后,当 type 为 module
时,node 默认将 .js
作为 esm 加载,因此当我们要输出 cjs 产物时,js 产物后缀为 .cjs
,类型描述文件后缀为 d.cts
;
反之,如果缺少 type 字段或者 type 为 commonjs
时, node 默认将 .js
文件作为 cjs 加载,因此当我们要输出 esm 产物时,js 产物后缀为 .mjs
,类型描述文件后缀为 d.mts
。
WARNING
在 bundleless 模式下使用时,我们会有一步额外的操作,那就是处理每个文件里的 import/export 语句。我们会给相对路径加上 js 文件后缀,可能是 .mjs
或者 .cjs
,这取决于你的包配置,此行为可以通过 redirect.autoExtension关闭。
注意 noUselessIndex 规则会破坏此行为,你需要禁用此规则
如果你需要在 bundleless 使用此配置,请补齐 index
,例如 utils 是一个文件夹, 你需要将 import * from './utils'
改写为 import * from './utils/index'
modern.config.ts
export default defineConfig({
buildConfig: {
autoExtension: true,
},
});
autoExternal
自动外置项目的 "dependencies"
和 "peerDependencies"
,不会将其打包到最终的 bundle 产物中。
- 类型:
boolean | object
- 默认值:
true
当我们希望关闭对于第三方依赖的默认处理行为时候,可以通过以下方式来实现:
modern.config.ts
export default defineConfig({
buildConfig: {
autoExternal: false,
},
});
这样对于 "dependencies"
和 "peerDependencies"
下面的依赖都会进行打包处理。如果只想要关闭其中某个下面的依赖处理,则可以使用
buildConfig.autoExternal
的对象形式:
modern.config.ts
export default defineConfig({
buildConfig: {
autoExternal: {
dependencies: false,
peerDependencies: false,
},
},
});
autoExternal.dependencies
是否需要外置项目的 "dependencies"
依赖。
autoExternal.peerDependencies
是否需要外置项目的 "peerDependencies"
依赖。
banner
提供为每个 JS , CSS 和 DTS 文件的顶部和底部注入内容的能力。
interface BannerAndFooter {
js?: string;
css?: string;
dts?: string;
}
- 类型:
BannerAndFooter
- 默认值:
{}
- 版本:
>=2.36.0
例如你想为 JS 和 CSS 文件添加版权信息:
import { moduleTools, defineConfig } from '@edenx/module-tools';
const copyRight = `/*
© Copyright 2020 example.com or one of its affiliates.
* Some Sample Copyright Text Line
* Some Sample Copyright Text Line
*/`;
export default defineConfig({
plugins: [moduleTools()],
buildConfig: {
banner: {
js: copyRight,
css: copyRight,
},
},
});
buildType
构建类型,bundle
会打包你的代码,bundleless
只做代码的转换。
- 类型:
'bundle' | 'bundleless'
- 默认值:
'bundle'
copy
将文件或目录拷贝到指定位置。
modern.config.ts
export default defineConfig({
buildConfig: {
copy: {
patterns: [{ from: './src/assets', to: '' }],
},
},
});
copy.patterns
- 类型:
CopyPattern[]
- 默认值:
[]
interface CopyPattern {
from: string;
to?: string;
context?: string;
globOptions?: globby.GlobbyOptions;
}
copy.options
type Options = {
concurrency?: number;
enableCopySync?: boolean;
};
-
默认值: { concurrency: 100, enableCopySync: false }
-
concurrency
: 指定并行执行多少个复制任务。
-
enableCopySync
: 使用 fs.copySync
,默认情况下 fs.copy
。
define
定义全局变量,注入到代码中
- 类型:
Record<string, string>
- 默认值:
{}
由于 define
功能是由全局文本替换实现的,所以需要保证全局变量值为字符串,更为安全的做法是将每个全局变量的值转化为字符串,如下所示:
modern.config.ts
export default defineConfig({
buildConfig: {
define: {
VERSION: require('./package.json').version || '0.0.0',
},
},
});
不过要注意:如果项目是一个 TypeScript 项目,那么你可能需要在项目源代码目录下的 .d.ts
文件里增加以下内容:
如果不存在 d.ts
文件,则可以手动创建。
env.d.ts
declare const YOUR_ADD_GLOBAL_VAR;
我们也可以进行环境变量替换:
import { defineConfig } from '@modern-js/module-tools';
export default defineConfig({
buildConfig: {
define: {
'process.env.VERSION': process.env.VERSION || '0.0.0',
},
},
});
通过上面的配置,我们就可以将下面这段代码:
// 编译前代码
console.log(process.env.VERSION);
在执行 VERSION=1.0.0 modern build
的时候,转换为:
// 编译后代码
console.log('1.0.0');
TIP
为了防止全局替换替换过度,建议使用时遵循以下两个原则:
- 全局常量使用大写
- 自定义全局常量前缀后缀,确保独一无二
dts
类型文件生成的相关配置,默认情况会生成。
{
abortOnError: true,
distPath: './',
only: false,
}
dts.abortOnError
用于控制在出现类型错误的时候,是否允许构建成功。
默认情况下,在出现类型错误的时候会导致构建失败。将 abortOnError
设置为 false
后,即使代码中出现了类型问题,构建依然会成功:
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
abortOnError: false,
},
},
});
WARNING
当关闭该配置后,无法保证类型文件能正常生成,且不保证内容正确。在 buildType: 'bundle'
时,即打包模式下,类型文件一定不会生成。
dts.distPath
类型文件的输出路径,基于 outDir 进行输出。
比如输出到 outDir
下面的 types
目录:
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
distPath: './types',
},
},
});
dts.enableTscBuild
开启 tsc '--build' 选项。当使用 project reference 时,
可以使用 '--build' 选项以实现项目之间的协同工作以加快构建速度。
此选项要求版本 > 2.43.0,
事实上,我们在 2.42.0 版本曾试验性地开启此选项,但其带来的许多问题使我们不得不动态开启。
当开启此选项时,为了满足构建需求,你必须显式地在 tsconfig.json 里设置 'declarationDir' 或者 'outDir',
如果你用的不是 TS >= 5.0 版本,你还需要显式地设置 'declaration' 和 'emitDeclarationOnly'。
- 类型:
boolean
- 默认值:
false
- 版本:
>2.43.0
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
enableTscBuild: true,
},
},
});
dts.only
是否在构建时只生成类型文件,不生成 JavaScript 产物文件。
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
only: true,
},
},
});
dts.respectExternal
当设为 false
时,不会打包任何三方包类型,设为 true
时,会根据 externals 来决定是否需要打包三方类型。
在对类型文件进行打包时,构建工具还未对 export 进行分析,因此当你引用的任何一个三方包出现类型错误时,都可能会中断当前的构建流程,这会导致构建流程不可控,因此我们可以通过这个配置来避免该问题。
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
respectExternal: false,
},
},
});
dts.tsconfigPath
废弃,使用 tsconfig 配置替代。
指定用于生成类型文件的 tsconfig 文件路径。
modern.config.ts
export default defineConfig({
buildConfig: {
dts: {
tsconfigPath: './other-tsconfig.json',
},
},
});
esbuildOptions
用于修改底层的 esbuild 配置。
例如,我们需要修改生成文件的后缀:
modern.config.ts
export default defineConfig({
buildConfig: {
esbuildOptions: options => {
options.outExtension = { '.js': '.mjs' };
return options;
},
},
});
例如,注册一个 esbuild 插件:
modern.config.ts
import { myEsbuildPlugin } from './myEsbuildPlugin';
export default defineConfig({
buildConfig: {
esbuildOptions: options => {
options.plugins = [myEsbuildPlugin, ...options.plugins];
return options;
},
},
});
在增加 esbuild 插件时,请注意你需要将插件加在 plugins 数组的头部,因为 Modern.js Module 内部也是通过一个 esbuild 插件介入到整个构建流程中去的,因此需要将自定义插件优先注册。
TIP
我们在原本 esbuild 构建的基础上做了许多扩展,因此使用此配置需要注意以下几点:
- 优先使用 Modern.js Module 提供的配置,例如 esbuild 并不支持
target: 'es5'
,但我们内部使用 SWC 支持了此场景,此时通过 esbuildOptions
设置target: 'es5'
会报错。
- 目前我们内部使用
enhanced-resolve
替代了 esbuild 的 resolve 解析算法,所以修改 esbuild resolve 相关配置无效,计划在未来会切换回来。
externalHelpers
默认情况下,输出的 JS 代码可能会依赖一些辅助函数来支持目标环境或者输出格式,这些辅助函数会被内联在需要它的文件中。
使用此配置,将会使用 SWC 对代码进行转换,将内联的辅助函数转换为从外部模块 @swc/helpers
导入这些辅助函数。
下面是使用该配置前后的产物变化比较。
开启前:
./dist/index.js
// 辅助函数
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
// ...
}
// 辅助函数
function _async_to_generator(fn) {
return function () {
// use asyncGeneratorStep
// ...
};
}
// 你的代码
export var yourCode = function () {
// use _async_to_generator
};
开启后:
./dist/index.js
// 从 @swc/helpers 导入的辅助函数
import { _ as _async_to_generator } from '@swc/helpers/_/_async_to_generator';
// 你的代码
export var yourCode = function () {
// use _async_to_generator
};
externals
用于在打包时排除一些外部依赖,避免将这些依赖打包到最终的 bundle 中。
type Externals = (string | RegExp)[];
- 默认值:
[]
- 构建类型:
仅支持 buildType: 'bundle'
- 示例:
modern.config.ts
export default defineConfig({
buildConfig: {
// 避免打包 React
externals: ['react'],
},
});
同 banner 配置,用于在输出文件末尾添加注释。
format
用于设置 JavaScript 产物输出的格式,其中 iife
和 umd
只在 buildType
为 bundle
时生效。
- 类型:
'esm' | 'cjs' | 'iife' | 'umd'
- 默认值:
cjs
format: esm
esm 代表 "ECMAScript 模块",它需要运行环境支持 import 和 export 语法。
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'esm',
},
});
format: cjs
cjs 代表 "CommonJS",它需要运行环境支持 exports、require 和 module 语法,通常为 Node.js 环境。
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'cjs',
},
});
format: iife
iife 代表 "立即调用函数表达式",它将代码包裹在函数表达式中,确保代码中的任何变量不会意外地与全局范围中的变量冲突,通常在浏览器环境中运行。
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'iife',
},
});
format: umd
umd 代表 "Universal Module Definition",用于在不同环境(浏览器、Node.js 等)中运行。umd 格式的模块可以在多种环境下使用,既可以作为全局变量访问,也可以通过模块加载器(如 RequireJS)进行模块化加载。
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'umd',
},
});
hooks
构建生命周期钩子,允许在构建流程的特定阶段注入自定义逻辑。
type HookList = {
name: string;
apply: (compiler: ICompiler) => void;
// 是否在 buildIn 钩子之后执行
applyAfterBuiltIn?: boolean;
};
我们可以在 apply 方法里拿到 compiler 实例,修改其属性,以及在不同阶段执行自定义逻辑,对于 Hook 的详细介绍,
参考使用 Hook 介入构建流程。
modern.config.ts
export default defineConfig({
buildConfig: {
buildType: 'bundle',
hooks: [
{
name: 'renderChunk',
apply: compiler => {
// any logic for compiler
compiler.hooks.renderChunk.tapPromise(
{ name: 'renderChunk' },
async chunk => {
return chunk;
},
);
},
},
],
},
});
input
指定构建的入口文件,数组形式可以指定目录。
type Input =
| string[];
| {
[name: string]: string;
}
- 默认值:
bundle
模式下默认为 ['src/index.ts']
,bundleless
模式下默认为 ['src']
数组用法:
在 bundle
模式下,下面的配置会以 src/index.ts
和 src/index2.ts
为入口分别进行构建。bundle
模式不支持配置 input
为目录。
modern.config.ts
export default defineConfig({
buildConfig: {
buildType: 'bundle',
input: ['src/index.ts', 'src/index2.ts'],
},
});
在 bundleless
模式下,下面的配置会同时处理 src/a
目录下的文件和 src/index.ts
文件。
modern.config.ts
export default defineConfig({
buildConfig: {
buildType: 'bundleless',
input: ['src/a', 'src/index.ts'],
},
});
在 bundleless
模式下,数组模式还支持使用 !
来过滤部分文件:
modern.config.ts
export default defineConfig({
buildConfig: {
buildType: 'bundleless',
input: ['src', '!src/*.spec.ts'],
},
});
上面的配置将打包 src
目录下的文件,同时会过滤以 spec.ts
为后缀的文件。这在测试文件与源码文件在同一个根目录下的情况会很有用。
对象用法:
当在 bundle 模式下需要修改产物的输出文件名称的时候,可以使用对象形式进行配置。
对象的 Key 是产物的文件名称,Value 是源码的文件路径。
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'esm',
input: {
'index.esm': './src/index.ts',
},
},
});
jsx
指定 JSX 的编译方式,默认支持 React 17 及更高版本,自动注入 JSX 运行时代码。
- 类型:
automatic | transform | preserve
- 默认值:
automatic
如果你需要支持 React 16,则可以设置 jsx
为 transform
:
modern.config.ts
export default defineConfig({
buildConfig: {
jsx: 'transform',
},
});
TIP
如果你不需要转换 JSX ,可以设置 jsx
为 preserve
, 但此时请不要使用 swc 做代码转换。
关于 JSX Transform 的更多说明,可以参考以下链接:
loader
试验性功能
此选项用来更改给定输入文件的解释方式。例如你需要将 js 文件当做 jsx 处理
modern.config.ts
export default defineConfig({
buildConfig: {
loader: {
'.js': 'jsx',
}
},
});
metafile
这个选项用于构建分析,开启该选项后,esbuild 会以 JSON 格式生成有关构建的一些元数据。
- 类型:
boolean
- 默认值:
false
- 构建类型:
仅支持 buildType: 'bundle'
开启 metafile
生成:
modern.config.ts
export default defineConfig({
buildConfig: {
buildType: 'bundle',
metafile: true,
},
});
在执行 build 构建后,产物目录下会生成 metafile-[xxx].json
文件,你可以通过 esbuild analyze 和 bundle-buddy 等工具进行可视化分析。
minify
使用 esbuild 或者 terser 压缩代码,也可以传入 terserOptions。
- 类型:
'terser' | 'esbuild' | false | object
- 默认值:
false
modern.config.ts
export default defineConfig({
buildConfig: {
minify: {
compress: {
drop_console: true,
},
},
},
});
outDir
指定构建的输出目录。
modern.config.ts
export default defineConfig({
buildConfig: {
outDir: './dist/esm',
},
});
platform
默认生成用于 Node.js 环境下的代码,你也可以指定为 browser
,会生成用于浏览器环境的代码。
查看esbuild.platform了解更多。
- 类型:
'browser' | 'node'
- 默认值:
'node'
modern.config.ts
export default defineConfig({
buildConfig: {
platform: 'browser',
},
});
redirect
在 buildType: 'bundleless'
构建模式下,会对引用路径进行重定向,确保指向了正确的产物,例如:
import './index.less'
会被改写成 import './index.css'
import icon from './close.svg'
会被改写成 import icon from '../asset/close.svg'
(依实际情况而定)
import * from './utils'
会被改写成 import * from './utils.mjs'
(如果生成了 utils.mjs,视实际情况而定)
在某些场景下,你可能不需要这些功能,那么可以通过此配置关闭它,关闭后,其引用路径将不会发生改变。
modern.config.ts
export default {
buildConfig: {
redirect: {
alias: false, // 关闭对别名路径的修改
style: false, // 关闭对样式文件路径的修改
asset: false, // 关闭对资源文件路径的修改
autoExtension: false, // 关闭对 js 文件后缀的修改
},
},
};
resolve
自定义模块解析选项
resolve.alias
基本用法和 alias 一致。
alias 的问题在于我们在 bundleless 场景下错误的处理了 Module ID 的情况:
import { createElement } from "react";
当我们配置了 alias: { react: 'react-native' }
后,结果会变成
import { createElement } from "./react-native";
一个 Module ID 被错误的处理成了相对路径,显然这是不符合预期的。
我们想要修复这个问题,但是这可能会破坏已有的项目,因此我们在 2.58.0 版本提供了 resolve.alias
来解决这个问题。
并且 resolve.alias
里移除了 alias 提供的默认值 { "@": "./src"}
如果你需要此功能,请使用 resolve.alias
。
在下一个大版本,resolve.alias
将会取代 alias
。
WARNING
- 注意此配置不要与 alias 混用。
- 注意此配置必须标注一个相对路径,例如
{ "@": "./src" }
而非 { "@": "src"}
。
resolve.mainFields
package.json 中,在解析包的入口点时尝试的字段列表。
- 类型:
string[]
- 默认值:取决于platform
- node: ['module', 'main']
- browser: ['module', 'browser', 'main']
- 版本:
>=2.36.0
例如,我们想要先加载 js:source
字段:
modern.config.ts
export default defineConfig({
buildConfig: {
resolve: {
mainFields: ['js:source', 'module', 'main'],
},
},
});
WARNING
resolve.mainFields
比 package.json 中 exports 字段的优先级低,如果一个入口点从 exports 成功解析,resolve.mainFields
将被忽略。
resolve.jsExtentions
支持隐式文件扩展名
- 类型:
string[]
- 默认值:
['.jsx', '.tsx', '.js', '.ts', '.json']
- 版本:
>=2.36.0
对于 css 文件,请不要使用隐式文件扩展名,目前 Module 仅支持 ['.less', '.css', '.sass', '.scss'] 后缀。
Node 的解析算法不会将 .mjs
和 cjs
视为隐式文件扩展名,因此这里默认也不会,但是可以通过更改此配置来包含:
modern.config.ts
export default defineConfig({
buildConfig: {
resolve: {
jsExtentions: ['.mts', 'ts'],
},
},
});
resolve.tsconfig
用于配置 enhanced-resolve 中的 tsconfig-paths-webpack-plugin,来支持解析 tsconfig.json 中的 alias 和嵌套 @
别名冲突的问题。
type Tsconfig = {
configFile: string,
references?: string[] | undefined,
};
- 默认值:
{ configFile: config.tsconfig, references: undefined }
- 版本:
>=2.61.1
modern.config.ts
export default defineConfig({
buildConfig: {
resolve: {
tsConfig: {
configFile: './tsconfig.json',
}
},
},
});
shims
在构建 cjs / esm 产物时注入一些垫片代码。
例如 __dirname
只能在 commonjs 里使用,开启此选项后,当产物格式为 esm 时,会将 __dirname
编译为 path.dirname(fileURLToPath(import.meta.url))
。
详细代码见 shims,
需要注意的是 esm shims 只会在 platform 为 node 时注入,因为用到了 url 模块。
- 类型:
boolean
- 默认值:
false
- 版本:
>=2.38.0
modern.config.ts
export default defineConfig({
buildConfig: {
shims: true,
},
});
sideEffects
配置模块的副作用
- 类型:
RegExg[] | (filePath: string, isExternal: boolean) => boolean | boolean
- 默认值:
undefined
通常情况下,我们通过 package.json 的 "sideEffects"
字段来配置模块的副作用,但是在某些情况下,三方包的 package.json 是不可靠的。
例如我们引用了一个三方包的样式文件。
import 'other-package/dist/index.css';
但是这个三方包的 package.json 里并没有将样式文件配置到 "sideEffects"
里。
other-package/package.json
{
"sideEffects": ["dist/index.js"]
}
同时你又设置了 style.inject 为 true
,在控制台可以看到类似的警告信息:
[LIBUILD:ESBUILD_WARN] Ignoring this import because "other-package/dist/index.css" was marked as having no side effects
这时候就可以使用这个配置项,手动配置模块的"sideEffects"
,配置支持正则和函数形式。
modern.config.ts
export default defineConfig({
buildConfig: {
sideEffects: [/\.css$/],
// or
// sideEffects: (filePath, isExternal) => /\.css$/.test(filePath),
},
});
TIP
添加此配置后,打包时将不会再读取 package.json 里的 "sideEffects"
字段。
sourceDir
指定构建的源码目录,默认为 src
,用于在 bundleless
构建时基于源码目录结构生成对应的产物目录。
等同于esbuild.outbase。
sourceMap
控制 sourceMap 如何生成。
- 类型:
boolean | 'inline' | 'external'
- 默认值:
false
sourceType
设置源码的格式。默认情况下,会将源码作为 EsModule 进行处理。当源码使用的是 CommonJS 的时候,需要设置 commonjs
。
- 类型:
'commonjs' | 'module'
- 默认值:
'module'
splitting
是否开启代码分割。
仅支持 format: 'esm' 和 format: 'cjs',查看esbuild.splitting了解更多。
style
配置样式相关的配置。
style.less
less 相关配置。
style.less.lessOptions
详细配置参考 less。
- 类型:
object
- 默认值:
{ javascriptEnabled: true }
style.less.additionalData
在入口文件起始添加 Less
代码。
- 类型:
string
- 默认值:
undefined
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
less: {
additionalData: `@base-color: #c6538c;`,
},
},
},
});
style.less.implementation
配置 Less
使用的实现库,在不指定的情况下,使用的内置版本是 4.1.3
。
- 类型:
string | object
- 默认值:
undefined
设置 object
类型时,可以指定 Less
的实现库。
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
less: {
implementation: require('less'),
},
},
},
});
string
类型时,指定 Less
的实现库的路径
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
less: {
implementation: require.resolve('less'),
},
},
},
});
sass
Sass 相关配置。
style.sass.sassOptions
详细配置参考 node-sass
style.sass.additionalData
在入口文件起始添加 Sass
代码。
- 类型:
string | Function
- 默认值:
undefined
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
sass: {
additionalData: `$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);`,
},
},
},
});
style.sass.implementation
配置 Sass
使用的实现库,在不指定的情况下,使用的内置版本是 1.5.4
。
- 类型:
string | object
- 默认值:
undefined
设置为 object
类型时,可以指定 Sass
的实现库。
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
sass: {
implementation: require('sass'),
},
},
},
});
string
类型时,指定 Sass
的实现库的路径
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
sass: {
implementation: require.resolve('sass'),
},
},
},
});
style.postcss
用于配置 PostCSS 的选项,传入的值会与默认配置通过 Object.assign
合并。注意 Object.assign
是浅拷贝,因此会完全覆盖内置的 plugins 数组。
详细配置请查看 PostCSS。
type PostcssOptions = {
processOptions?: ProcessOptions;
plugins?: AcceptedPlugin[];
};
const defaultConfig = {
plugins: [
// 以下插件默认启用
require('postcss-flexbugs-fixes'),
require('postcss-media-minmax'),
require('postcss-nesting'),
// 以下插件仅在 target 为 `es5` 时启用
require('postcss-custom-properties'),
require('postcss-initial'),
require('postcss-page-break'),
require('postcss-font-variant'),
],
};
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
postcss: {
plugins: [yourPostCSSPlugin],
},
},
},
});
style.inject
配置打包模式下是否将 CSS 样式插入到 JavaScript 代码中。
将 inject
设置为 true
来开启此功能:
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
inject: true,
},
},
});
开启后,你会看到源码中引用的 CSS 代码被包含在了打包后的 JS 产物中。
例如,你在源码里写了 import './index.scss'
,那么在产物中你会看到以下代码:
dist/index.js
// node_modules/style-inject/dist/style-inject.es.js
function styleInject(css, ref) {
// ...
}
var style_inject_es_default = styleInject;
// src/index.scss
var css_248z = '.body {\n color: black;\n}';
style_inject_es_default(css_248z);
TIP
开启 inject
后,你需要注意以下几点:
- CSS 文件中的
@import
不会被处理。如果你的 CSS 文件中有 @import
,那么你需要在 JS 文件中手动引入 CSS 文件(less,scss 文件不需要,因为它们会有预处理)。
- 需要考虑
sideEffects
的影响。默认情况下,我们的构建器会认为 CSS 是有副作用的,如果你的项目中或者三方包的 package.json 设置了 sideEffects
字段并且没有包含此 CSS 文件,那么你将会得到一个警告:
[LIBUILD:ESBUILD_WARN] Ignoring this import because "src/index.scss" was marked as having no side effects by plugin "libuild:adapter"
此时可以通过配置 sideEffects 来解决。
style.autoModules
根据文件名自动启用 CSS Modules。
- 类型:
boolean | RegExp
- 默认值:
true
true
: 为以 .module.css
.module.less
.module.scss
.module.sass
文件名结尾的样式文件启用 CSS Modules。
false
: 禁用 CSS Modules.
RegExp
: 为匹配正则条件的所有文件启用 CSS Modules.
style.modules
CSS Modules 配置。
一个常用的配置是 localsConvention
,它可以改变 CSS Modules 的类名生成规则。
modern.config.ts
export default defineConfig({
buildConfig: {
style: {
modules: {
localsConvention: 'camelCaseOnly',
},
},
},
});
对于以下样式:
.box-title {
color: red;
}
你可以使用 styles.boxTitle
来访问。
详细配置查看 postcss-modules
style.tailwindcss
用于修改 Tailwind CSS 的配置项。
- 类型:
object | Function
- 默认值:
modern.config.ts
const tailwind = {
content: ['./src/**/*.{js,jsx,ts,tsx}', './config/html/**/*.{html,ejs,hbs}'],
};
启用 Tailwind CSS
在使用 style.tailwindcss
之前,你需要启用 Modern.js Module 的 Tailwind CSS 插件。
请阅读「使用 Tailwind CSS」 章节来了解开启方式。
类型
值为 object
类型时,与默认配置通过 Object.assign
合并。
值为 Function
类型时,函数返回的对象与默认配置通过 Object.assign
合并。
其他的使用方式和 Tailwind CSS 一致: 快速传送门。
注意事项
注意:
- 如果你同时使用了
tailwind.config.{ts,js}
文件和 tools.tailwindcss
选项,那么 tools.tailwindcss
定义的配置会优先生效,并覆盖 tailwind.config.{ts,js}
中定义的内容。
- 如果你同时使用了
designSystem
配置项,那么 Tailwind CSS 的 theme
配置将会被 designSystem
的值所覆盖。
其他配置的使用方式与 Tailwind CSS 官方用法一致,请参考 tailwindcss - Configuration。
target
target
用于为生成的 JavaScript 代码设置目标环境。它让 Modern.js Module 将目标环境无法识别的 JavaScript 语法转换为在这些环境中可用的低版本 JavaScript 语法。
type Target =
| 'es5'
| 'es6'
| 'es2015'
| 'es2016'
| 'es2017'
| 'es2018'
| 'es2019'
| 'es2020'
| 'es2021'
| 'es2022'
| 'esnext';
例如,将代码编译到 es5
语法:
modern.config.ts
export default defineConfig({
buildConfig: {
target: 'es5',
},
});
transformImport
提供与 babel-plugin-import 等价的能力和配置,基于 SWC 实现,使用此配置,将会使用 SWC 对代码进行转换。
数组元素为一个 babel-plugin-import 的配置对象。配置对象可以参考 options。
使用示例:
modern.config.ts
export default defineConfig({
buildConfig: {
transformImport: [
// babel-plugin-import 的 options 配置
{
libraryName: 'foo',
style: true,
},
],
},
});
参考「Import 插件——注意事项」
transformLodash
是否模块化 lodash 的导入,删除未使用的 lodash 模块,从而减少 lodash 代码体积。这项优化基于 babel-plugin-lodash 和 swc-plugin-lodash 实现。
使用此配置,将会使用 SWC 对代码进行转换。
当开启此选项时,Modern.js Module 会自动将 lodash 的代码引用指向子路径。
比如:
input.js
import _ from 'lodash';
import { add } from 'lodash/fp';
const addOne = add(1);
_.map([1, 2, 3], addOne);
转换后的代码:
output.js
import _add from 'lodash/fp/add';
import _map from 'lodash/map';
const addOne = _add(1);
_map([1, 2, 3], addOne);
tsconfig
TypeScript 配置文件的路径。
- 类型:
string
- 默认值:
tsconfig.json
- 版本:
>=2.36.0
modern.config.ts
export default defineConfig({
buildConfig: {
tsconfig: 'tsconfig.build.json',
},
});
umdGlobals
指定 UMD 产物外部导入的全局变量。
- 类型:
Record<string, string>
- 默认值:
{}
modern.config.ts
export default defineConfig({
buildConfig: {
umdGlobals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
});
此时,react
和 react-dom
会被看做是外部导入的全局变量,不会被打包进 UMD 产物中,而是通过 global.React
和 global.ReactDOM
的方式进行访问。
umdModuleName
指定 UMD 产物的模块名。
- 类型:
string | Function
- 默认值:
name => name
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'umd',
umdModuleName: 'myLib',
},
});
此时 UMD 产物会去挂载到 global.myLib
上。
TIP
- 需要遵守 UMD 规范,UMD 产物的模块名不能和全局变量名冲突。
- 模块名会被转换为驼峰命名,如
my-lib
会被转换为 myLib
,可参考toIdentifier。
同时函数形式可以接收一个参数,为当前打包文件的输出路径
modern.config.ts
export default defineConfig({
buildConfig: {
format: 'umd',
umdModuleName: path => {
if (path.includes('index')) {
return 'myLib';
} else {
return 'myLib2';
}
},
},
});
```import { aliases } from '../../../../../../toolkit/utils/dist/compiled/browserslist';
import { createElement } from 'react';