跳至内容

自定义

选项

从 Razzle 3.2 开始,你可以使用选项修改 Razzle 的某些部分。

我们在此处显示默认选项

//./razzle.config.js
module.exports = {
options: {
verbose: false, // set to true to get more info/error output
debug: { // debug flags
options: false, // print webpackOptions that will be used in webpack config
config: false, // print webpack config
nodeExternals: false // print node externals debug info
},
buildType: 'iso', // or 'spa', 'serveronly', 'iso-serverless' and 'serveronly-serverless'
cssPrefix: 'static/css',
jsPrefix: 'static/js',
mediaPrefix: 'static/media',
staticCssInDev: false, // static css in development build (incompatible with css hot reloading)
browserslist: undefined, // or what your apps package.json says
enableSourceMaps: true,
enableReactRefresh: false,
enableTargetBabelrc: false, // enable to use .babelrc.node and .babelrc.web
enableBabelCache: true,
forceRuntimeEnvVars: [], // force env vars to be read from env e.g. ['HOST', 'PORT']
disableWebpackbar: false, // can be true to disable all environments or target to disable specific environment such as "node" or "web"
staticExport: {
parallel: 5, // how many pages to render at a time
routesExport: 'routes',
renderExport: 'render',
scriptInline: false,
windowRoutesVariable: 'RAZZLE_STATIC_ROUTES',
windowRoutesDataVariable: 'RAZZLE_STATIC_DATA_ROUTES'
},
},
};

未来将添加更多选项,现在的一些实验性选项将移至此处。

插件

从 Razzle 2.0 开始,你可以添加自己的插件来修改设置。

使用插件

你可以在项目中安装并将其添加到 razzle.config.js 中来使用 Razzle 插件。请参阅特定插件的 README.md,但一般来说,流程大致如下...

yarn add razzle-plugin-xxxx
//./razzle.config.js
module.exports = {
plugins: ['xxxx'],
};

编写插件

插件只是一组函数,它们修改并返回 Razzle/webpack/jest 配置。

有五个函数可用于关联到 Razzle 配置。

  • modifyOptions - 修改在 razzle.config.js 中的 options 键中传递给 Razzle 的默认 Razzle 选项和选项。
  • modifyPaths - 修改默认的 Razzle 路径。
  • modifyWebpackOptions - 修改将用于配置 webpack/webpack 加载器和插件的一些默认选项。
  • modifyWebpackConfig - 修改创建的 webpack 配置。
  • modifyJestConfig - 修改用于运行应用程序测试的 jest 配置。

这是一个使用所有五个函数的完整插件,通常您只需要 modifyWebpackConfig 和/或 modifyWebpackOptions

'use strict';
module.exports = {
modifyOptions({
webpackObject, // the imported webpack node module
options: {
pluginOptions, // the options passed to the plugin ({ name:'pluginname', options: { key: 'value'}})
razzleOptions, // the default options/ options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
},
}) {
// Do some stuff...
return razzleOptions;
},
modifyPaths({
webpackObject, // the imported webpack node module
options: {
pluginOptions, // the options passed to the plugin ({ name:'pluginname', options: { key: 'value'}})
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
},
paths, // the default paths that will be used by Razzle.
}) {
// Do some stuff...
return paths;
},
modifyWebpackOptions({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
webpackObject, // the imported webpack node module
options: {
pluginOptions, // the options passed to the plugin ({ name:'pluginname', options: { key: 'value'}})
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
webpackOptions, // the default options that will be used to configure webpack/ webpack loaders and plugins
},
paths, // the modified paths that will be used by Razzle.
}) {
if (target === 'web') {
// client only
}
if (target === 'node') {
// server only
}
if (dev) {
// dev only
} else {
// prod only
}
// Do some stuff...
return webpackOptions;
},
modifyWebpackConfig({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
webpackConfig, // the created webpack config
webpackObject, // the imported webpack node module
options: {
pluginOptions, // the options passed to the plugin ({ name:'pluginname', options: { key: 'value'}})
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
webpackOptions, // the modified options that was used to configure webpack/ webpack loaders and plugins
},
paths, // the modified paths that will be used by Razzle.
}) {
if (target === 'web') {
// client only
}
if (target === 'node') {
// server only
}
if (dev) {
// dev only
} else {
// prod only
}
// Do some stuff...
return webpackConfig;
},
modifyJestConfig({
jestConfig, // the created jest config
webpackObject, // the imported webpack node module
options: {
pluginOptions, // the options passed to the plugin ({ name:'pluginname', options: { key: 'value'}})
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
},
paths, // the modified paths that will be used by Razzle.
}) {
// Do some stuff...
return jestConfig;
},
};

插件还支持使用 Promise,此示例使用 modifyWebpackConfig,但所有钩子都支持 Promise。

'use strict';
module.exports = {
modifyWebpackConfig({
env: { target, dev },
webpackConfig,
webpackObject,
options: { pluginOptions, razzleOptions, webpackOptions },
paths,
}) {
return new Promise(async resolve => {
if (target === 'web') {
// client only
}
if (target === 'node') {
// server only
}
if (dev) {
// dev only
await getDevcert();
} else {
// prod only
}
// Do some stuff...
resolve(webpackConfig);
});
},
};

使用范围包

Razzle 支持使用范围包的插件。

将您的插件命名为 @scope-name/razzle-plugin-<name>

并在您的 razzle.config.js 中按如下方式引用它

//./razzle.config.js
module.exports = {
  plugins: ['@scope-name/name'],
};

请注意,省略了 razzle-plugin-

自定义 Babel 配置

Razzle 将 razzle/babel 预设包含在您的应用程序中,其中包含编译 React 应用程序和服务器端代码所需的一切。但如果您想扩展默认的 Babel 配置,也是可以的。

首先,您只需在应用程序顶部定义一个 .babelrc 文件,如果找到此类文件,我们将把它视为“真相来源”,因此它还需要定义 Razzle 需要的内容,即 razzle/babel 预设。

这里有一个示例 .babelrc 文件

{
"presets": ["razzle/babel"],
"plugins": []
}

您可以查看此文件以了解 razzle/babel 包含的预设。

要添加预设/插件(而不配置它们),您可以这样做

{
"presets": ["razzle/babel"],
"plugins": ["@babel/plugin-proposal-do-expressions"]
}

自定义配置添加预设/插件,请在 razzle/babel 预设中这样做

{
"presets": [
[
"razzle/babel",
{
"preset-env": {},
"transform-runtime": {},
"class-properties": {}
}
]
],
"plugins": []
}

要了解有关每个配置可用选项的更多信息,请访问其文档网站。

Razzle 对服务器端编译使用当前 Node.js 版本。

"preset-env" 上的 modules 选项应保持为 false,否则会关闭 webpack 代码分割。

扩展 Webpack

您还可以扩展底层 webpack 配置。在项目的根目录中创建一个名为 razzle.config.js 的文件。

插件中支持的所有钩子函数在此也受支持。为简洁起见,我们在此仅展示一个函数。

在 Razzle 3.3 中,modify 已弃用。在 Razzle 4.0 中,它被 modifyWebpackConfig 取代。

// razzle.config.js
module.exports = {
modifyWebpackConfig({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
webpackConfig, // the created webpack config
webpackObject, // the imported webpack node module
options: {
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
webpackOptions, // the modified options that will be used to configure webpack/ webpack loaders and plugins
},
paths, // the modified paths that will be used by Razzle.
}) {
if (target === 'web') {
// client only
}
if (target === 'node') {
// server only
}
if (dev) {
// dev only
} else {
// prod only
}
// Do some stuff...
return webpackConfig;
},
};

提供一个建议:razzle.config.js 是一个逃生手段。然而,由于这只是 JavaScript,因此您可以并且应该将您的 modify* 函数发布到 npm,以便在您的项目中重复利用。例如,想象一下,您添加了某些自定义 webpack 加载器并将其作为包发布到 npm,包名为 my-razzle-modifications。然后,您可以像这样编写您的 razzle.config.js

// razzle.config.js
const modifications = require('my-razzle-modifictions');
module.exports = modifications;

最后但并非最不重要的是,如果您发现自己需要更多定制的设置,Razzle 是非常容易修改的。有一个 webpack 配置工厂,有 1000 行代码和 5 个脚本(buildstarttestexportinit)。路径设置是毫不犹豫地从 create-react-app中获取的,而代码的其余部分与日志记录相关。

Razzle 3.2 的新功能

razzle.config.js modify 也支持使用 Promise

// razzle.config.js
module.exports = {
modifyWebpackConfig({
env: { target, dev },
webpackConfig,
webpackObject,
options: { razzleOptions, webpackOptions },
paths,
}) {
return new Promise(async resolve => {
if (target === 'web') {
// client only
}
if (target === 'node') {
// server only
}
if (dev) {
// dev only
await getDevcert();
} else {
// prod only
}
// Do some stuff...
resolve(webpackConfig);
});
},
};

CSS 模块

Razzle 支持使用 Webpack 的 css-loader,即可获得 CSS 模块。只需导入扩展名为 .module.css 的 CSS 文件,Razzle 将使用 css-loader 处理该文件即可。

import React from 'react';
import styles from './style.module.css';
const Component = () => <div className={styles.className} />;
export default Component;

Polyfill

IE 9、IE 10 和 IE 11 的 Polyfill 不再默认包含在内(但您可以选择包含!)我们已经放弃了对 Internet Explorer 9、10 和 11 的默认支持。如果您仍然需要支持这些浏览器,请按照以下说明进行操作。

首先,安装 react-app-polyfill

npm install react-app-polyfill

yarn add react-app-polyfill 接下来,在 src/client.js: 的最顶部放置以下行之一:

import 'react-app-polyfill/ie9'; // For IE 9-11 support
import 'react-app-polyfill/ie11'; // For IE 11 support

外部模块的转换

如果您需要将带有箭头函数等的外部模块转换

确保模块未被 externalize,并添加到 babelRule 中。

// razzle.config.js
'use strict';
module.exports = {
modifyWebpackOptions({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
options: {
webpackOptions, // the default options that will be used to configure webpack/ webpack loaders and plugins
}
}) {
webpackOptions.notNodeExternalResMatch = (request, context) => {
return /themodule|anothermodule/.test(request)
};
webpackOptions.babelRule.include = webpackOptions.babelRule.include.concat([
/themodule/,
/anothermodule/
]);
return webpackOptions;
}
};

绝对导入

您可以配置应用程序以支持使用绝对路径导入模块。这可以通过在项目的根目录中配置 jsconfig.json 或 tsconfig.json 文件来完成。如果您在项目中使用 TypeScript,那么您将已经拥有一个 tsconfig.json 文件。

下面是一个 JavaScript 项目的 jsconfig.json 文件示例(如果您使用 TypeScript 的话,则为 tsconfig.json)。如果该文件不存在,则可以创建该文件

{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}

如需让 Jest 测试运行器与绝对导入协同运行,你需要向你的 package.json 添加 jest 配置选项

{
"name": "my-razzle-app",
"version": "1.0.0",
"license": "MIT",
/* ...dependencies, etc... */
"jest": {
"moduleDirectories": ["node_modules", "src"]
}
}

既然你已将你的项目配置为支持绝对导入,如果你想导入位于 src/components/Button.js 的一个模块,那么你可以像这样导入该模块

import Button from 'components/Button';

别名路径/模块

你可以将你的应用程序配置为支持使用别名路径来导入模块。这可以通过在项目的根目录配置一个 jsconfig.json 或 tsconfig.json 文件来实现。如果你在项目中使用 TypeScript,那么你应该已经有了 tsconfig.json 文件。

{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"@extra/*": ["../extra/*"]
}
}
}

既然你已将你的项目配置为支持别名路径导入,如果你想导入位于 extra/components/Button.js 的一个模块,那么你可以像这样导入该模块

import Button from '@extra/components/Button';

实验性

Razzle 已支持一些实验性功能。即将推出。