Create React App:不使用eject,自定义webpack配置
Create React App提供了一套非常不错的配置,能够上手即用,并且提供了“eject”功能,让你能够自己接管所有的配置项。 但是,如果当你仅仅是想微调一下Webpack的配置呢?而并不是接管所有的配置项。你可能想要增加SASS或者SCSS的支持,或者使用自己定义的.eslintrc文件。(译者的使用场景是在webpack中增加alias) 让我们开始讲解如何操作。 警告! 当Create React App变化时,特别是它使用的react-scripts包变化时,很有可能导致我们的代码需要一些修复。如果官方修改了webpack的结构,或者导出方式,我们的代码将出现问题,这时就需要你自己去了解如何修复它们。所以,再强调一次,如果你觉得这种方式有问题,请不要这么做!(译者觉得原作者有点夸张了) 破解Create React App Create React App的基础被封装在“react-scripts”包中,可以在package.json中的“dependencies”的列表里了解到。 我们将使用rewire来创建猴子补丁(运行时动态替换),使得我们在执行之前对Webpack配置进行定制。 下面这个文件是这个项目中最重要的部分。我建议在您的CRA项目中建立一个名为“scripts”的目录,并将这些代码放入scripts/customized-config.js文件中。你可以任意命名,不过(稍后我们将用到这个文件名)。 scripts/customized-config.js /* 本模块运行react-scripts里的脚本 (Create React App) 可以自定义webpack配置,通过在项目根目录创建"config-overrides.dev.js" 、 "config-overrides.prod.js" 文件. A config-overrides file should export a single function that takes a config and modifies it as necessary. module.exports = function(webpackConfig) { webpackConfig.module.rules[0].use[0].options.useEslintrc = true; }; */ var rewire = require('rewire'); var proxyquire = require('proxyquire'); switch(process.argv[2]) { // The "start" script is run during development mode case 'start': rewireModule('react-scripts/scripts/start.js',loadCustomizer('../config-overrides.dev')); break; // The "build" script is run to produce a production bundle case 'build': rewireModule('react-scripts/scripts/build.js',loadCustomizer('../config-overrides.prod')); break; // The "test" script runs all the tests with Jest case 'test': // Load customizations from the config-overrides.testing file. // That file should export a single function that takes a config and returns a config let customizer = loadCustomizer('../config-overrides.testing'); proxyquire('react-scripts/scripts/test.js',{ // When test.js asks for '../utils/createJestConfig' it will get this instead: '../utils/createJestConfig': (...args) => { // Use the existing createJestConfig function to create a config,then pass // it through the customizer var createJestConfig = require('react-scripts/utils/createJestConfig'); return customizer(createJestConfig(...args)); } }); break; default: console.log('customized-config only supports "start","build",and "test" options.'); process.exit(-1); } // Attempt to load the given module and return null if it fails. function loadCustomizer(module) { try { return require(module); } catch(e) { if(e.code !== "MODULE_NOT_FOUND") { throw e; } } // If the module doesn't exist,return a // noop that simply returns the config it's given. return config => config; } function rewireModule(modulePath,customizer) { // Load the module with `rewire`,which allows modifying the // script's internal variables. let defaults = rewire(modulePath); // Reach into the module,grab its global 'config' variable,// and pass it through the customizer function. // The customizer should *mutate* the config object,because // react-scripts imports the config as a `const` and we can't // modify that reference. let config = defaults.__get__('config'); customizer(config); } 为了跑通代码,你需要安装一些额外的依赖包:
你可以通过注释来了解它是如何工作的。最有趣的部分是位于底部的rewireModule方法,它使用rewire库来查看另一个文件,并获取定义在那里的配置变量的引用。 一旦你完成了这个操作,就可以为开发,生产,测试环境编写用来覆盖的配置文件。这一部分完全取决于你——无论你对CRA的Webpack配置做了什么改动,你都可以直接去做。 这些文件应该直接在CRA文件夹的根目录下,所有3个文件都是可选的。如果您想要重新配置它们的位置,只需改变上面“loadCustomizer”调用的路径。只是不要把它们放在“src”中就可以。 下面是一些开发环境替换配置的例子: config-overrides.dev.js const path = require('path'); module.exports = function(config) { // 使用你自己的 ESLint let eslintLoader = config.module.rules[0]; eslintLoader.use[0].options.useEslintrc = true; // Add the SASS loader second-to-last // (last one must remain as the "file-loader") let loaderList = config.module.rules[1].oneOf; loaderList.splice(loaderList.length - 1,{ test: /.scss$/,use: ["style-loader","css-loader","sass-loader"] }); } 还需要创建一个config-overrides.prod.js文件具有相同的内容。开发过程中使用的是dev文件(例如npm start),在构建期间使用prod文件(例如,npm run build)。 为了让刚刚的配置生效,你需要安装SASS loader,和它的依赖node-sass:
最后,要让这些新代码生效,你需要更改package.json,调用这些新的脚本,而不是默认的react-scripts的脚本。要做到这一点,可以用以下方法替换“start”、“build”和“test”。 package.json "scripts": { "start": "node scripts/customized-config start","build": "node scripts/customized-config build","test": "node scripts/customized-config test --env=jsdom",} 示例项目 译者补充: /* * 替换react为preact * */ let alias = config.resolve.alias alias["react"] = "preact-compat" alias["react-dom"] = "preact-compat" 相关资料: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |