Note: In the latest example
, we support using ts
files to write config
for better type support. Use this in combination with this documentation to reduce the possibility of errors. If you find the documentation lagging behind or existing configurations cannot meet your needs, please submit an issue
.
This chapter will introduce some configurations supported by config.ts|js
. For detailed configuration, you can directly check this file.
Configuration files can be defined through config.ts|js
files and passed in real-time when calling the core.render
method. The two configurations will be merged.
Note: The config.ts|js
file will be uniformly placed in the build/config.js
path after compilation, so when you use relative paths to reference external files in the configuration file, please use syntax like require cwd
. Currently, importing external ts
files is not supported. Since documentation updates may not be timely, it is recommended to use the latest ssr-types
types as the main reference.
import { render } from 'ssr-core'
const stream = await render<Readable>(this.ctx, userConfig)
Rendering mode
string
ssr
Webpack/Vite
Determines whether the current application uses server-side rendering or client-side rendering through the rendering mode
boolean
false
Webpack/Vite
Whether to compile components as stream
for return to accelerate display speed. Default is false
, i.e., return normal html
strings
Record<string, string>
undefined
Webpack/Vite
Configure alias
aliases
boolean
false
Webpack/Vite
Flag for current runtime environment, determined by NODE_ENV === development
string
#app
Webpack/Vite + Vue2/3 + React17/18
Set the application’s root node id
starting with #
. For React
scenarios, you need to manually modify <div id="app">
in layout/index.tsx
to the specified node
string
static
Webpack/Vite
Set the build directory for static file resources (js|css|image), default is build/client/static
. When set to config.assetsDir = 'assets'
, the build directory becomes build/client/assets
string
/
Webpack/Vite
The publicPath
for static resources. Generally no configuration needed for local development environment. No configuration needed for production environment if using local static resource directory. If you need to deploy through separate CDN
service, configure to specific CDN
address like https://g.alicdn.com/path/xxx
boolean
true
Webpack
Whether build artifacts have hash
, enabled by default in production environment, not recommended to disable
number
3000
Webpack/Vite
The port that the Node.js
service listens on during local development. Can also be specified through environment variables SERVER_PORT=9000 ssr start
number
8999
Webpack
The port for webpack-dev-server
to host frontend static resources during local development. The Node.js Server
will automatically proxy
static resources. No modification needed unless there are special requirements
{define?: { base?: Record<string, string> client?: Record<string, string> server?: Record<string, string> }}
{}
Webpack/Vite
Add universal definePlugin
configuration that works on both client and server sides. Compatible with Webpack/Vite
scenarios
((ctx: ISSRContext) => string[]) | string[]
[]
Webpack/Vite
Additional js chunk name
that needs to be loaded during initialization, usually used together with splitChunks
configuration. If other name
chunks are generated, developers can view specific chunkName
through the http://localhost:3000/asset-manifest.json
file
module.exports = {
extraJsOrder: ['styles.js'], // Load additional styles.chunk.js file at the bottom of the page, production environment automatically gets the correct hash file
extraCssOrder: ['styles.css'] // Load additional styles.chunk.css file at the head of the page, production environment automatically gets the correct hash file
}
Advanced usage, load split vendor
on demand
import type { UserConfig, ISSRMidwayKoaContext } from 'ssr-types'
const userConfig: UserConfig = {
chainClientConfig: chain => {
chain.optimization.splitChunks({
...chain.optimization.get('splitChunks'),
cacheGroups: {
'vendor-swiper': {
test: (module: any) => {
return module.resource &&
/\.js$/.test(module.resource) &&
module.resource.match('swiper')
},
name: 'vendor-swiper',
priority: 3
},
...chain.optimization.get('splitChunks').cacheGroups
}
})
},
extraJsOrder: (ctx) => {
const ctxWithType = ctx as ISSRMidwayKoaContext
// Only load vendor-swiper when accessing the homepage
if (ctxWithType.path === '/') {
return ['vendor-swiper.js']
}
}
}
export { userConfig }
((ctx: ISSRContext) => string[]) | string[]
[]
Webpack/Vite
Additional css chunk name
that needs to be loaded during initialization, usually used together with splitChunks
configuration. Usage is the same as extraJsOrder
module.exports = {
extraJsOrder: ['styles.js'],
extraCssOrder: ['styles.css']
}
Advanced usage to control the loading priority order of all generated js chunks
in the page. The processed parameters come from the complete result of merging JsOrder
and extraJsOrder
. No modification needed unless there are special circumstances.
Type: Record<string, number> | ((params: {chunkName: string}) => Record<string, number>)
Default: undefined
version: latest
Applicable scenarios: Webpack/Vite
Default loading order is as follows, where chunkName
represents the chunkName.chunk.js
file built from the frontend page-level component corresponding to the current request route
const jsOrder = isVite ? ['Page.js'] : ['runtime~Page.js', 'vendor.js', 'common-vendor.js', 'Page.js', 'layout-app.js']
module.exports = {
// Unset items have a unified priority of 0, higher priority loads first
jsOrderPriority: {
'vendor.js': 1,
'common-vendor.js': 2 // Higher priority
},
jsOrderPriority: ({ chunkName }) => ({
// Supports passing in a function, with the parameter being the ChunkName of the current request page, can be used directly. For example, 'index' in index.chunk.js is the chunkName for the homepage, 'detail-id' in detail-id.chunk.js is the chunkName for the detail page
// Note that chunkName acquisition depends on server-side runtime logic, so in spa build mode, there is no chunkName parameter
`${chunkName}.js`: 1,
'common-vendor.js': 2 // Higher priority
})
}
Advanced usage to control the loading priority order of all generated css chunks
in the page. The processed parameters come from the complete result of merging cssOrder
and extraCssOrder
. No modification needed unless there are special circumstances.
Type: Record<string, number> | ((params: {chunkName: string}) => Record<string, number>)
Default: undefined
version: latest
Applicable scenarios: Webpack/Vite
Default loading order is as follows, where chunkName
represents the chunkName.chunk.css
file built from the frontend page-level component corresponding to the current request route
const cssOrder = ['vendor.css', 'common-vendor.css', 'Page.css', 'layout-app.css']
Specific usage is the same as jsOrderPriority
above
'all'|string[]
undefined
Vue2/3 + Webpack/Vite
Only effective in production environment. Used to customize which cssChunk
needs to be inline
with style
tags. The collection of cssChunks
can be viewed in asset-manifest.json
. Need to ensure that the path path.join(process.cwd(), './build', '${chunkPath}')
exists in local files at runtime. When the value is all
, all cssChunk
will be inlined at runtime by default.
// asset-manifest.json
{
"index~detail-id.css": "/client/static/index~detail-id.8894e773.chunk.css",
"index~detail-id.js": "/client/static/index~detail-id.1fe746c4.chunk.js",
"vendor.js": "/client/static/vendor.6bb41bc3.chunk.js",
"Page.css": "/client/static/Page.18a19313.chunk.css",
"Page.js": "/client/static/Page.13ad4870.chunk.js",
"detail-id.css": "/client/static/detail-id.03b9e22b.chunk.css",
"detail-id.js": "/client/static/detail-id.e30e8bf6.chunk.js",
"detail-id-fetch.js": "/client/static/detail-id-fetch.3af0feb0.chunk.js",
"index.css": "/client/static/index.48cc7c95.chunk.css",
"index.js": "/client/static/index.71a22404.chunk.js",
"index-fetch.js": "/client/static/index-fetch.bf6bd7af.chunk.js",
"runtime~Page.js": "/client/static/runtime~Page.e43266a7.js"
}
You can also override the local asset-manifest.json
with absolute paths, for example Page.js: /User/xxxx/Page.js
for custom control. The framework will directly use that path when it detects an absolute path
babelCore.transformOptions
undefined
Webpack/Vite
Recommended to use this configuration to modify the default babel
configuration, compatible with Webpack/Vite
scenarios
export {
babelOptions: {
include: [] as RegExp[], // Third-party modules that need additional processing
exclude: [] as RegExp[], // Business code files that don't need processing, usually used to specify pure JS files that have already been built once for reuse
presets: [] // Less commonly used
plugins: [] // Usually use this configuration to add plugins
}
}
webpackDevServer.Configuration
See specific configuration file above in the article
Webpack
webpack-dev-server
startup configuration
Use webpack-chain to modify the common Webpack
build configuration for server/client
.
Note: Most developer needs should modify baseConfig
rather than independent serverConfig
or clientConfig
For example, to add raw-loader
for parsing markdown
files
module.exports = {
chainBaseConfig: (chain, isServer) => {
chain.module
.rule('markdown')
.test(/\.md$/)
.use('raw-loader')
.loader(require.resolve('raw-loader'))
.end()
}
}
Use webpack-chain to modify the common Webpack
build configuration for server
Use webpack-chain to modify the common Webpack
build configuration for client
RegExp[]|string[]
[/\.(css|less|sass|scss)$/]
Webpack/Vite
New feature: Supports settings in both Vite/Webpack
modes, equivalent to vite.ssr.noexternal
When processing server
side build modules, we default to using externals
mode for all third-party modules, i.e., not processed by Webpack
during build, directly loaded from node_modules
at runtime. However, for some modules that only provide esm
format, or files that cannot be directly executed in non-Node.js
environments, such as jsx|less|sass|css
type files, runtime errors will occur. For this type of special module, we provide whitelist configuration to set the server-side build configuration externals
whitelist, i.e., modules that need to be processed by Webpack
.
whiteList
has two forms: string[]
and RegExp[]
, representing different meanings. Please choose according to actual needs
string[]
: When the value of whiteList
is string
instead of RegExp
, the framework will treat it as a module name and deeply traverse the module’s own dependencies and dependencies of dependencies. For example, antd
’s own dependencies
depend on other modules. To avoid duplicate configuration, these modules also need to be configured in the whitelist together. To reduce workload, the framework itself adds a relatively simple dependency automatic traversal collection strategy to automatically collect all modules that need to be processed. In Serverless
deployment mode, we usually use the string[]
form because we only install production
environment node_modules
in this scenario
RegExp[]
: Only matches dependencies that the regular expression can match. Can be used when the application has installed complete node_modules
or when it’s certain that sub-dependencies of dependencies don’t need to be processed. This makes the program logic simpler and provides faster build speed.
string|undefined
undefined
Webpack/Vite
Add a unified prefix
to frontend routes, such as /${prefix}/
, /${prefix}/detail/:id
. Functionally equivalent to the basename
option provided by React-Router
and the base
option provided by Vue-Router
.
Similarly, after setting this parameter, all frontend route navigation operations will add this prefix
object
{}
Webpack/Vite
Uses http-proxy-middleware at the underlying layer for proxying. The framework simply passes through parameters. See http-proxy-middleware
documentation for specific configuration
module.exports = {
proxy: {
'/api': {
target: 'http://www.example.org',
changeOrigin: true
}
}
}
boolean
userConfig.https ? userConfig.https : !!process.env.HTTPS
Webpack/Vite
Whether to enable the underlying webpack-dev-server
’s https
mode, needs to be used synchronously with the Node.js
https
service on port 3000
. Setting to true
will use the default self-signed certificate. When this certificate cannot be trusted, you can also pass certificate configuration consistent with the Node.js
server side.
Note: It is more recommended to use whistle to start https
proxy service during local development
const fs = require('fs')
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
// Can read configuration in server-side code through ssr-server-utils loadConfig api, pass to corresponding server-side framework to set certificate
https: isProd ? {} : {
key: fs.readFileSync('./scripts/https/https.key'),
cert: fs.readFileSync('./scripts/https/https.crt')
}
}
// How to read on server side, using nest.js as example
// main.ts
import { loadConfig } from 'ssr-common-utils'
const { https } = loadConfig()
const app = await NestFactory.create<NestExpressApplication>(AppModule, isProd ? {} : {
httpsOptions: https
})
boolean
true
Webpack
Whether to enable code splitting, enabled by default. Must be enabled in Vite mode
Array<{tagName?: string, describe: object, content: string }>|(ctx: ISSRContext) => Array<{tagName?: string, describe: object, content: string }>
[]
Webpack/Vite
Only used in Vue
scenarios. The latest version supports two types, allowing different script content output based on the current request context, commonly used in dynamic prefix scenarios
Used to insert custom script
in the page header through configuration. To avoid affecting expected functionality, this content is not escaped
. To avoid xss
, ensure the security of inserted script code
tagName
customizes the tag name to be created, defaults to script
tag
describe
field references Vue createElement for setting script
tag attribute
content
is the content of the script
module.exports = {
customeHeadScript: [
// Vue3 directly write attr properties
{
tagName: 'xxx', // Default value is script
describe: {
type: 'text/javascript',
src: 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js'
},
content: ''
},
// Vue2 needs to be wrapped in attrs property, see corresponding Vue version documentation for details
{
describe: {
attrs: {
type: 'text/javascript',
src: 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js'
}
},
content: ''
},
// Directly insert script content
{
content: `var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?xxxx";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();`
}
],
}
Array<{describe: object, content: string }>|(ctx: ISSRContext) => Array<{describe: object, content: string }>
[]
Webpack/Vite
Only used in Vue
scenarios, same meaning as above. Static resource files loaded at the bottom of the page. Needs to be used with <slot name="customeFooterScript" />
. If the current example
was created previously and layout/index.vue
doesn’t have this slot
, you need to manually add it
module.exports = {
// Here you need to check the documentation of the loader version used by the framework
css: () => {
return {
loaderOptions: {
cssOptions: any // css-loader options see https://www.npmjs.com/package/css-loader/v/5.2.7
less?: any // less-loader options see https://www.npmjs.com/package/less-loader/v/7.3.0
sass?: any // sass-loader options see https://www.npmjs.com/package/sass-loader/v/10.2.0
postcss: {
options: Object|Function // Recommended to use object see https://www.npmjs.com/package/postcss-loader/v/4.3.0
plugins: any[]
}
}}
}
}
Default: () => {}
Applicable scenarios: Webpack/Vite
Used to add user-defined configurations for css-loader
, less-loader
, and postcss-loader
. Needs to be in function return
form
boolean
undefined
Webpack/Vite
When enabled, server-side data fetching will make parallel requests to layout fetch
and page fetch
. If page fetch
requests depend on the return of layout fetch
, please do not use this option
Webpack/Vite
Refer to the antd
official documentation. In the ssr
framework, less-loader@^7.0.0
is used by default with the following configuration. Requires ssr
framework version >=5.5.21
css: () => {
return {
loaderOptions: {
less: {
// Pass parameters to less-loader
lessOptions: {
modifyVars: {
'primary-color': '#fff',
'link-color': '#1DA57A',
'border-radius-base': '20px'
},
javascriptEnabled: true
}
}
}
}
}
Type: Object
Default: {}
version: >=5.5.23
Applicable scenarios: Webpack/Vite
vue-loader options when building server-side bundle
Type: Object
Default: {}
version: >=5.5.23
Applicable scenarios: Webpack/Vite
vue-loader options when building client-side bundle
Type: { enable: boolean }
Default: { enable: false }
Applicable scenarios: Vue3 + Webpack
Whether to enable vue-i18n
internationalization plugin
Type: boolean
Default: false
Applicable scenarios: Webpack
Usually used in conjunction with corejsOptions
below. After enabling, we will append the following configuration in @babel/preset-env. It will automatically inject corresponding polyfill
based on the usage of current code. For specific behavior, please check the relevant instructions in @babel/preset-env
. This option is used to be compatible with low-end browsers.
const corejsVersion = coerce(require('core-js/package.json').version).major
const corejsOptions = userConfig.corejs ? {
corejs: {
version: corejsVersion,
proposals: corejsVersion === 3
},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
},
useBuiltIns: 'usage',
shippedProposals: corejsVersion === 2,
...userConfig.corejsOptions
} : {}
类型: Object
默认: 如上所示
该配置用于覆盖默认的 corejsOptions
配置
类型: RegExp
默认: undefined
version: >5.5.45
生效场景: Webpack
框架默认不使用 babel
来编译 node_modules
中的代码,这会拖慢构建速度,且十分没有必要。一个质量合格的模块应当在发布前对自身进行构建。针对模块质量不合格的特殊情况,我们提供了配置来让开发者指定具体的模块参与 babel
编译
module.exports = {
babelExtraModule: [/module-name/]
}
针对同一前端 path
可以对应多个路由时控制约定式路由优先级例如 /foo
, 可以同时匹配 /:page
/foo
。用于约定式路由解析生成的数组排序。数字越大代表优先级越高。没有显示指定的路由优先级统一为 0
类型: Record<string, number>
默认: undefined
version: >5.5.89
生效场景: Webpack/Vite
module.exports = {
routerPriority: {
'/': 1,
'/detail/:id': 2 // 优先级更高
}
}
自定义 Nest.js
场景服务启动成功提示文案,不填写则为 Server is listening on ${https ? 'https' : 'http'}://localhost:${serverPort}
类型: string
默认: undefined
生效场景: Webpack/Vite
module.exports = {
nestStartTips: 'xxx'
}
指定前端页面进行编译构建。在某些情况下我们只需要调试某个前端页面而不是所有页面,此时可以通过该配置来选择需要调试的页面进行构建来提升构建速度减小代码体积。但要注意,如果生产环境仍然是所有页面都需要发布,需要在生产环境禁用此配置,否则构建出来的代码只包含当前选中的页面。
类型: routerOptimize?: { include?: string[] exclude?: string[] }
默认: undefined
version: >=5.6.12
生效场景: Webpack/Vite
module.exports {
routerOptimize: {
// 注意,include 和 exclude 不能同时设置只能设置一项
include: ['/'], // 选择需要构建的前端路由 path
exclude: ['/'] // 排除不需要构建的前端路由 path
}
}
类型: boolean
默认: undefined
version: >=6.2.2
生效场景: Vue3
+ Webpack/Vite
仅在 Vue3 ssr build --html
场景下生效,通于降级 html
渲染的场景不存在服务器环境,此时需要让客户端使用 hashRouter
。
import type { UserConfig } from 'ssr-types'
const userConfig: UserConfig = {
hashRouter: true
}
export { userConfig }
在 vite
模式下的 config
配置
type viteConfig?: () => {
common?: {
// 双端通用配置
extraPlugin?: PluginOption | PluginOption[]
server?: ServerOptions // 对应 vite.server 配置
}
client?: {
// 只在客户端生效的配置
defaultPluginOptions?: any // 为默认装载的插件定义 options, vue3 场景是 @vitejs/plugin-vue, react 场景是 @vitejs/plugin-react
otherConfig?: ViteConfig
processPlugin?: (plugins: PluginOption[]) => PluginOption[] // 传入当前使用的插件列表,返回新的插件列表,通过此方法来新增/移除框架默认插件
}
server?: {
// 只在服务端生效的配置
externals?: string[] // 强制 externals 的第三方依赖
defaultPluginOptions?: any
otherConfig?: ViteConfig
processPlugin?: (plugins: PluginOption[]) => PluginOption[]
}
}
为了防止用户的配置覆盖框架默认的必要配置导致启动构建失败,所以这里我们暂时只会开放部分配置让开发者使用,若无法满足你的需求,可以提 issue
来反馈,我们会根据实际情况新增配置项
参考文件 html
类型: string
默认: \<!DOCTYPE html> \<html lang="en"> \<head> \<meta charset="UTF-8"> \<meta http-equiv="X-UA-Compatible" content="IE=edge"> \<meta name="viewport" content="width=device-width, initial-scale=1.0"> \<title>Document\</title> cssInject jsHeaderManifest \</head> \<body> \<div id="app">\</div> hashRouterScript jsFooterManifest jsManifest \</body> \</html>
生效场景: Webpack/Vite
作为 ssr build --html
的构建模版,开发者可自行设置 title, meta
等标签信息,其余模版插入内容请不要修改保持不变。
boolean
undefined
Vue2/3 + Webpack/Vite
高级用法,只在特定场景下适用。
开启 bigpipe
配置后,框架将会将完整的 html
文档拆分为两部分返回,分别是无实际意义内容的 layout
和有实际内容的 children
部分。
此功能用于开发者需要提前返回包含页面所需的静态资源文件给浏览器提前加载,而无需等待服务端渲染接口响应和页面完全渲染完毕才返回完整的 html
文档。
例如如下的 layout
组件
<template>
<!-- 注:Layout 只会在服务端被渲染,不要在此运行客户端有关逻辑,不要删除 rem 初始化以外的任何初始设置 -->
<html>
<head>
<meta charSet="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<title>Serverless Side Render for Vue</title>
<slot name="remInitial" />
<!-- 包含 css 静态资源文件,以及预请求 js 静态资源文件 -->
<slot name="injectHeader" />
</head>
<!-- -------我是分割线----------- -->
<body>
<slot name="content" />
</body>
</html>
</template>
将会以分割线为结点,分为前后两部分进行内容返回。
import { render } from 'ssr-core'
// 此时将不会调用 fetch 返回的内容为不包含实际页面组件内容的 layout 组件
const headHtmlStr = await render(ctx, {
bigpipe: true
stream: false, // 注意这里要使用字符串形式的返回数据类型
});
// 使用基于 koa 的框架需要手动设置 status
// ctx.status = 200
// 提前返回包含静态资源文件的 html 头部 也可提前返回 loading
res.write(headHtmlStr.split('<body>')[0]);
res.write('<body><!-- loading -->');
// 第二次调用 render 后返回完整的页面内容
const bodyhtmlStr = await render(ctx, {
stream: false
});
// 与首次返回的页面内容进行组装拼接为完整的 html 文档结构
// 这里也可以根据 html 字符串的大小决定是直接返回字符串给客户端,还是将字符串转换为 stream 后再进行返回
res.write(bodyhtmlStr.split('<body>')[1]);
res.end();
通常在 ssr
过程中接口和页面元素节点过多导致渲染时间过长进而页面白屏时间较长的场景可能会使用到此能力。可通过提前返回 <head>
的部分,预加载样式和脚本文件,也可以通过分块提前返回 loading
或骨架屏来替代 <body>
返回前的白屏。
string
build/staticConfig.js
Vue2/3 + Webpack/Vite
设置静态构建文件的路径。默认值 build/staticConfig.js
目前不允许修改!!!。
使用场景:针对一些需要在构建时获取生成 customeHeadScript|customeFooterScript
的业务场景例如构建时通过接拉取脚本配置信息,减少运行时的性能损耗。开发者可以自定义构建逻辑,在 ssr build
执行之前或者之后(如果要兼容 SPA静态html文件
场景需要在 ssr build
执行之前完成)生成 build/staticConfig.js
文件。框架将会在运行时加载此文件读取其中的内容。
$ node xxx.js && ssr build
可以在 ssr build
执行前通过调用自己编写的脚本来生成此文件,也可以通过 chainClientWebpack
等配置在 ssr build
时监听 webpack
事件来生成。生成 SPA
的逻辑将会在 webpack
构建结束后再执行。
文件示例如下
// build/staticConfig.js
// 只能使用 commonjs 语法兼容 Node.js 环境
exports.customeHeadScript= [
// 规范与上文的 customeHeadScript 保持完全一致
// Vue3 直接写 attr 属性即可
{
tagName: 'script', // 默认值为 script
describe: {
type: 'text/javascript',
src: 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js'
},
content: ''
}
]
此文件建议使用 exports.xxx
语法进行导出。目前支持 customeHeadScript|customeFooterScript
的导出逻辑。
string
undefined
all
自定义前端插件来替换例如 ssr-plugin-vue3
的逻辑,常用于在 ssr-plugin-vue3
二次开发的情况
number
1024 * 16
react
react
场景设置默认的stream
缓冲区大小,默认为16kb
,当页面体积过大超过限制时会渲染失败,此时需要通过该配置设置默认缓冲区大小,或者修改返回类型为 string
,单位byte (1024*1024 = 1mb)
config.js
文件在 Node.js 环境也会被加载,如果直接在顶部 require
模块可能会导致模块体积过大
,降低应用启动速度,对于一些只在构建逻辑中才会用到的模块我们建议在必要的函数当中再 require
加载。
以添加 postcss
插件为例module.exports = {
css: () => {
// css 在 vue-cli 中是直接配置对象,但在本框架需要使用函数来 return 具体对象,这样我们只有在本地打包阶段才会去 require 要用到的依赖。在生产环境服务启动的时候不会 require
const pxtoviewport = require('postcss-px-to-viewport')
return {
loaderOptions: {
postcss: {
plugins: [
pxtoviewport({
viewportWidth: 375
})
]
}
}
}
}
}
chainWebpackConfig
的方式来让用户可以修改默认配置但绝大部分情况下你不需要去修改默认的配置。我们默认的配置是基于 create-react-app
生成的配置上做了一些优化。已经极力做到最优。如果确定需要修改默认配置,应该先看看配置有无提供额外选项直接设置例如 css.loaderOptions
,而不是通过 WebpackChain
工具去重新设置规则。这样极易导致错误。
我们后续可能会兼容一些 vue-cli
支持的配置,但不是全部。我们并不打算做成大而全的工具这样只会变成大黑盒。配置越多只会增加错误出现的可能性。参考 vue-cli
工具 400多个文件,3w 行源码 580个待解决 issue
。