задний план
Для проектов, созданных с помощью шаблонов CRA, если вы хотите изменить конфигурацию сборки, вы обычно можете выбратьnpm run eject
После того, как конфигурация всплывает, магия меняется. Однако извлечение является необратимой операцией: после появления конфигурации вы не сможете выполнить официальные шаги по обновлению версии проекта с реактивным скриптом.
Если вы хотите переписать конфигурацию CRA без извлечения, в настоящее время разработаны следующие методы.
- Официально поддерживается CRA
--scripts-version
Параметры, используйте собственный переписанный пакет реактивных скриптов при создании проекта - использоватьreact-app-rewired + customize-craОбъединение конфигураций переопределения
- использоватьcracoПереопределить конфигурацию
Второй метод немного сложнее третьего, я испытал его на себе, и мы заметили последние изменения.AntDesign4Чиновник также начал рекомендоватьcracoЧего же мы ждем? Давайте действовать быстро. Сегодня мы в основном подробно обсуждаем это здесь.cracoЭто также удобно для всех, чтобы дать лучшие предложения.
Шаги настройки
- Во-первых, используйте
create-react-app
Создайте проект, здесь нас зовутmy-project
npx create-react-app my-project
- Введите каталог проекта и установите основные зависимости
yarn add antd @craco/craco craco-less @babel/plugin-proposal-decorators babel-plugin-import -D
3. Изменитьpackage.json
серединаscripts
{
"scripts":{
"start": "set PORT=5000 && craco start FAST_REFRESH=true",
"build": "set GENERATE_SOURCEMAP=false && craco build",
"analyzer": "env NODE_ENV=production BUILD_ANALYZER=true yarn start",
"test": "craco test"
}
}
4. Создайте корневой каталог проектаcraco.config.js
документ
/* craco.config.js */
module.exports = {
...
}
Несколько переменных окружения используются выше:
PORT
стартовый порт
GENERATE_SOURCEMAP
Генерировать ли при упаковкеsourceMap
BUILD_ANALYZER
анализ компиляции выходных файлов
Базовая конфигурация завершена, и следующим шагом будет обработка различных конфигураций.Полную структуру файла конфигурации craco.config.js можно подробно запросить в официальной документации craco:Configuration Overview.
Расширить конфигурацию Babel
Хотя конфигурация babel может быть определена в configure, craco также предоставляет ярлык для отдельной записи, добавления
@babel/preset-env
Пример конфигурации выглядит следующим образом:
/* craco.config.js */
module.exports = {
babel: {
presets: [
[
'@babel/preset-env',
{
modules: false, // 对ES6的模块文件不做转化,以便使用tree shaking、sideEffects等
useBuiltIns: 'entry', // browserslist环境不支持的所有垫片都导入
// https://babeljs.io/docs/en/babel-preset-env#usebuiltins
// https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md
corejs: {
version: 3, // 使用core-js@3
proposals: true,
},
},
],
],
plugins: [
// 配置 babel-plugin-import
['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }, 'antd'],
// 配置解析器
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }],
["babel-plugin-styled-components", { "displayName": true }]
],
loaderOptions: {},
loaderOptions: (babelLoaderOptions, { env, paths }) => { return babelLoaderOptions; }
},
}
Проверьте компиляцию модуля
new WebpackBar({ profile: true }),
new CircularDependencyPlugin({
exclude: /node_modules/,
include: /src/,
failOnError: true,
allowAsyncCycles: false,
cwd: process.cwd()
})
Наблюдайте за процессом упаковки
const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin')
module export = {
webpack: {
plugins: [
// 查看打包的进度
new SimpleProgressWebpackPlugin()
]
}
}
Изменить выходной каталог пакета
module.exports = {
webpack: {
configure: (webpackConfig, {
env, paths
}) => {
// paths.appPath='public'
paths.appBuild = 'dist'
webpackConfig.output = {
...webpackConfig.output,
// ...{
// filename: whenDev(() => 'static/js/bundle.js', 'static/js/[name].js'),
// chunkFilename: 'static/js/[name].js'
// },
path: path.resolve(__dirname, 'dist'), // 修改输出文件目录
publicPath: '/'
}
return webpackConfig
}
}
}
Если вы считаете, что это громоздко, вы также можете использовать webpack для настройки покрытия напрямую.Вероятно, так много информации о webpackConfig:
Горячее обновление Hot-loader extension
Как запустить горячее обновление, чтобы избежать частых обновлений
Часто используемые решения для горячего обновления
react-hot-loader
КРАко также помог нам предоставить дваcraco-plugin-react-hot-reload
,craco-fast-refresh
react-hot-loader настроен следующим образом (портал)
step1:webpack.config.js中引入别名配置解除相关警告
yarn add @hot-loader/react-dom
module.exports = {
// ...
resolve: {
alias: {
'react-dom': '@hot-loader/react-dom',
},
},
};
step2:注入引用App.js
import { hot } from 'react-hot-loader/root'
function App {
return (
<div>ceshi</div>
)
}
export default hot(App)
craco-plugin-react-hot-reload настроен следующим образом (портал)
/* craco.config.js */
const reactHotReloadPlugin = require('craco-plugin-react-hot-reload')
const reactHotReloadPlugin = require('craco-plugin-react-hot-reload')
module.exports = {
plugins: [{
plugin: reactHotReloadPlugin
}]
}
craco-fast-refresh настроен следующим образом (портал)
Это новый плагин craco, обнаруженный недавно, в отличие от
react-hot-loader
Гораздо проще в использовании, нулевая конфигурация, нет необходимости изменять код проекта, и говорят, что производительность лучше.
step1:增加插件
/* craco.config.js */
const FastRefreshCracoPlugin = require('craco-fast-refresh')
module.exports = () => {
return {
plugins: [{
plugin: FastRefreshCracoPlugin
}],
};
};
step2: 注入引用App.js
import React from 'react'
import { hot } from 'react-hot-loader'
const App = () => <div>Hello World!</div>
export default hot(module)(App)
Конфигурация темы antd пользовательская тема
Настройте цвет темы antd, вы можете выбрать одну из следующих схем по желанию
Объединить меньше вариантов
step1:运行 yarn add craco-less
step2:引入 const CracoLessPlugin = require('craco-less')
step3:配置
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: {
'@primary-color': '#1DA57A'
},
javascriptEnabled: true
}
}
}
}
В то же время craco также предоставляет специальный плагин для интеграции antd (портал) комплектация другая
Индивидуальная поддержка Craco
craco-antd includes:
- Less (provided by craco-less)
- babel-plugin-import to only import the required CSS, instead of everything
- An easy way to customize the theme. Set your custom variables in ./antd.customize.less
step1: yarn add craco-antd
step2: const CracoAntDesignPlugin = require('craco-antd')
step3
{
plugin: CracoAntDesignPlugin,
options: {
customizeTheme: {
'@primary-color': '#FF061C'
}
}
}
противcustomizeTheme
Если вы хотите отделиться, вы можете принять следующий план
step1: 新建antd.customize.less文件
---------
@primary-color: #FF061C;
---------
step2:读取模式
{
plugin: CracoAntDesignPlugin,
options: {
customizeThemeLessPath: path.join(__dirname,"antd.customize.less")}
}
Условно говоря, он будет более лаконичным в использовании, и его рекомендуется использовать.
Суммировать
На самом деле можно настроить все конфигурации сборки cra без извлечения конфигурации.Это было подробно объяснено ранее.Если вам это нужно, вы можете пойти и посмотреть (портал). Следовательно, в последующем кодировании мы можем использовать эти два метода для создания собственной конфигурации веб-пакета.
Уведомление:
Конфигурация craco будет взаимоисключающей и будет использоваться с осторожностью.
Ниже приведена моя полная конфигурация craco.config.js, соответствующаяdemoЛегко ссылаться на
craco также предоставляет некоторые другие плагины для добавления в соответствии с реальной ситуацией (портал)
/* craco.config.js */
/**
* TODO: 区分环境 —— NODE_ENV
* - whenDev ☞ process.env.NODE_ENV === 'development'
* - whenTest ☞ process.env.NODE_ENV === 'test'
* - whenProd ☞ process.env.NODE_ENV === 'production'
*/
const {
when, whenDev, whenProd, whenTest, ESLINT_MODES, POSTCSS_MODES
} = require('@craco/craco')
const webpack = require('webpack')
const CracoLessPlugin = require('craco-less')
const CracoAntDesignPlugin = require('craco-antd')
const CracoVtkPlugin = require('craco-vtk')
const WebpackBar = require('webpackbar')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const FastRefreshCracoPlugin = require('craco-fast-refresh')
const TerserPlugin = require('terser-webpack-plugin')
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin')
const {
BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const DashboardPlugin = require('webpack-dashboard/plugin')
const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin')
const path = require('path')
// 判断编译环境是否为生产
const isBuildAnalyzer = process.env.BUILD_ANALYZER === 'true'
const pathResolve = pathUrl => path.join(__dirname, pathUrl)
module.exports = {
webpack: {
// 别名配置
alias: {
'@': pathResolve('.'),
src: pathResolve('src'),
assets: pathResolve('src/assets'),
common: pathResolve('src/common'),
components: pathResolve('src/components'),
hooks: pathResolve('src/hooks'),
pages: pathResolve('src/pages'),
store: pathResolve('src/store'),
utils: pathResolve('src/utils')
// 此处是一个示例,实际可根据各自需求配置
},
plugins: [
// webpack构建进度条
new WebpackBar({
profile: true
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// 查看打包的进度
new SimpleProgressWebpackPlugin(),
// 时间转换工具采取day替换moment
new AntdDayjsWebpackPlugin(),
// // 新增模块循环依赖检测插件
...whenDev(
() => [
new CircularDependencyPlugin({
exclude: /node_modules/,
include: /src/,
failOnError: true,
allowAsyncCycles: false,
cwd: process.cwd()
}),
// webpack-dev-server 强化插件
new DashboardPlugin(),
new webpack.HotModuleReplacementPlugin()
], []
),
/**
* 编译产物分析
* - https://www.npmjs.com/package/webpack-bundle-analyzer
* 新增打包产物分析插件
*/
...when(
isBuildAnalyzer, () => [
new BundleAnalyzerPlugin({
analyzerMode: 'static', // html 文件方式输出编译分析
openAnalyzer: false,
reportFilename: path.resolve(__dirname, `analyzer/index.html`)
})
], []
),
...whenProd(
() => [
// new TerserPlugin({
// // sourceMap: true, // Must be set to true if using source-maps in production
// terserOptions: {
// ecma: undefined,
// parse: {},
// compress: {
// warnings: false,
// drop_console: true, // 生产环境下移除控制台所有的内容
// drop_debugger: true, // 移除断点
// pure_funcs: ['console.log'] // 生产环境下移除console
// }
// }
// }),
// 打压缩包
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')/div>),
threshold: 1024,
minRatio: 0.8
})
], []
)
],
//抽离公用模块
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0
},
vendor: {
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
}
}
},
/**
* 重写 webpack 任意配置
* - configure 能够重写 webpack 相关的所有配置,但是,仍然推荐你优先阅读 craco 提供的快捷配置,把解决不了的配置放到 configure 里解决;
* - 这里选择配置为函数,与直接定义 configure 对象方式互斥;
*/
configure: (webpackConfig, {
env, paths
}) => {
// paths.appPath='public'
paths.appBuild = 'dist' // 配合输出打包修改文件目录
// webpackConfig中可以解构出你想要的参数比如mode、devtool、entry等等,更多信息请查看webpackConfig.json文件
/**
* 修改 output
*/
webpackConfig.output = {
...webpackConfig.output,
// ...{
// filename: whenDev(() => 'static/js/bundle.js', 'static/js/[name].js'),
// chunkFilename: 'static/js/[name].js'
// },
path: path.resolve(__dirname, 'dist'), // 修改输出文件目录
publicPath: '/'
}
/**
* webpack split chunks
*/
// webpackConfig.optimization.splitChunks = {
// ...webpackConfig.optimization.splitChunks,
// ...{
// chunks: 'all',
// name: true
// }
// }
// 返回重写后的新配置
return webpackConfig
}
},
babel: {
presets: [],
plugins: [
// AntDesign 按需加载
['import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true
}, 'antd'],
['@babel/plugin-proposal-decorators', {
legacy: true
}] // 用来支持装饰器
],
loaderOptions: {},
loaderOptions: (babelLoaderOptions, {
env, paths
}) => {
return babelLoaderOptions
}
},
/**
* 新增 craco 提供的 plugin
*/
plugins: [
// 热更新
...whenDev(
() => [{
plugin: FastRefreshCracoPlugin
}, {
plugin: CracoVtkPlugin()
}, {
plugin: new AntdDayjsWebpackPlugin()
}], []
),
// 方案1、配置Antd主题less
// {
// plugin: CracoLessPlugin,
// options: {
// lessLoaderOptions: {
// lessOptions: {
// modifyVars: { '@primary-color': '#1DA57A' },
// javascriptEnabled: true
// }
// }
// }
// },
// 方案2、配置Antd主题
// {
// plugin: CracoAntDesignPlugin,
// options: {
// customizeTheme: {
// '@primary-color': '#FF061C'
// }
// }
// },
// 方案3、配置Antd主题
{
plugin: CracoAntDesignPlugin,
options: {
customizeThemeLessPath: path.join(
__dirname,
"antd.customize.less"
),
},
},
],
devServer: {
port: 9000,
proxy: {
'/api': {
target: 'https://placeholder.com/',
changeOrigin: true,
secure: false,
xfwd: false,
}
}
}
}
В то же время мы также можем посмотреть, какие API нам предоставил официальный представитель.
const { when, whenDev, whenProd, whenTest, ESLINT_MODES, POSTCSS_MODES } = require("@craco/craco");
module.exports = {
reactScriptsVersion: "react-scripts" /* (default value) */,
style: {
modules: {
localIdentName: ""
},
css: {
loaderOptions: { /* Any css-loader configuration options: https://github.com/webpack-contrib/css-loader. */ },
loaderOptions: (cssLoaderOptions, { env, paths }) => { return cssLoaderOptions; }
},
sass: {
loaderOptions: { /* Any sass-loader configuration options: https://github.com/webpack-contrib/sass-loader. */ },
loaderOptions: (sassLoaderOptions, { env, paths }) => { return sassLoaderOptions; }
},
postcss: {
mode: "extends" /* (default value) */ || "file",
plugins: [],
env: {
autoprefixer: { /* Any autoprefixer options: https://github.com/postcss/autoprefixer#options */ },
stage: 3, /* Any valid stages: https://cssdb.org/#staging-process. */
features: { /* Any CSS features: https://preset-env.cssdb.org/features. */ }
},
loaderOptions: { /* Any postcss-loader configuration options: https://github.com/postcss/postcss-loader. */ },
loaderOptions: (postcssLoaderOptions, { env, paths }) => { return postcssLoaderOptions; }
}
},
eslint: {
enable: true /* (default value) */,
mode: "extends" /* (default value) */ || "file",
configure: { /* Any eslint configuration options: https://eslint.org/docs/user-guide/configuring */ },
configure: (eslintConfig, { env, paths }) => { return eslintConfig; },
loaderOptions: { /* Any eslint-loader configuration options: https://github.com/webpack-contrib/eslint-loader. */ },
loaderOptions: (eslintOptions, { env, paths }) => { return eslintOptions; }
},
babel: {
presets: [],
plugins: [],
loaderOptions: { /* Any babel-loader configuration options: https://github.com/babel/babel-loader. */ },
loaderOptions: (babelLoaderOptions, { env, paths }) => { return babelLoaderOptions; }
},
typescript: {
enableTypeChecking: true /* (default value) */
},
webpack: {
alias: {},
plugins: [],
configure: { /* Any webpack configuration options: https://webpack.js.org/configuration */ },
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
jest: {
babel: {
addPresets: true, /* (default value) */
addPlugins: true /* (default value) */
},
configure: { /* Any Jest configuration options: https://jestjs.io/docs/en/configuration. */ },
configure: (jestConfig, { env, paths, resolve, rootDir }) => { return jestConfig; }
},
devServer: { /* Any devServer configuration options: https://webpack.js.org/configuration/dev-server/#devserver. */ },
devServer: (devServerConfig, { env, paths, proxy, allowedHost }) => { return devServerConfig; },
plugins: [
{
plugin: {
overrideCracoConfig: ({ cracoConfig, pluginOptions, context: { env, paths } }) => { return cracoConfig; },
overrideWebpackConfig: ({ webpackConfig, cracoConfig, pluginOptions, context: { env, paths } }) => { return webpackConfig; },
overrideDevServerConfig: ({ devServerConfig, cracoConfig, pluginOptions, context: { env, paths, proxy, allowedHost } }) => { return devServerConfig; },
overrideJestConfig: ({ jestConfig, cracoConfig, pluginOptions, context: { env, paths, resolve, rootDir } }) => { return jestConfig },
},
options: {}
}
]
};
Разве не здорово использовать так много информации? Если вы хотите исследовать, действуйте быстро и добивайтесь прогресса вместе.