自定义
选项
从 Razzle 3.2 开始,你可以使用选项修改 Razzle 的某些部分。
我们在此处显示默认选项
//./razzle.config.jsmodule.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.jsmodule.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.jsmodule.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.jsconst modifications = require('my-razzle-modifictions');module.exports = modifications;
最后但并非最不重要的是,如果您发现自己需要更多定制的设置,Razzle 是非常容易修改的。有一个 webpack 配置工厂,有 1000 行代码和 5 个脚本(build
、start
、test
、export
和 init
)。路径设置是毫不犹豫地从 create-react-app中获取的,而代码的其余部分与日志记录相关。
Razzle 3.2 的新功能
razzle.config.js
modify 也支持使用 Promise
// razzle.config.jsmodule.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 supportimport '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 已支持一些实验性功能。即将推出。