UNPKG

3.6 kBJavaScriptView Raw
1// @ts-check
2const debug = require('debug')('find-webpack')
3const path = require('path')
4const fs = require('fs')
5const findYarnWorkspaceRoot = require('find-yarn-workspace-root')
6const mockEnv = require('mocked-env')
7
8const tryLoadingWebpackConfig = (webpackConfigPath) => {
9 debug('trying to load webpack config from %s', webpackConfigPath)
10 // Do this as the first thing so that any code reading it knows the right env.
11 const envName = 'development'
12 // @ts-ignore
13 const restoreEnv = mockEnv({
14 BABEL_ENV: envName,
15 NODE_ENV: envName,
16 })
17 try {
18 let webpackOptions = require(webpackConfigPath)
19 if (typeof webpackOptions === 'function') {
20 webpackOptions = webpackOptions(envName)
21 }
22 debug('webpack options: %o', webpackOptions)
23 return webpackOptions
24 } catch (err) {
25 debug('could not load react-scripts webpack')
26 debug('error %s', err.message)
27 debug(err)
28 restoreEnv()
29 }
30}
31
32const tryVueCLIScripts = () => {
33 const webpackConfigPath = path.resolve(
34 findYarnWorkspaceRoot() || process.cwd(),
35 'node_modules',
36 '@vue',
37 'cli-service',
38 'webpack.config.js',
39 )
40
41 debug('path to Vue CLI resolved webpack.config.js: %s', webpackConfigPath)
42 return tryLoadingWebpackConfig(webpackConfigPath)
43}
44
45const tryRootProjectWebpack = () => {
46 const webpackConfigPath = path.resolve(
47 findYarnWorkspaceRoot() || process.cwd(),
48 'webpack.config.js',
49 )
50
51 debug('path to root webpack.config.js: %s', webpackConfigPath)
52 return tryLoadingWebpackConfig(webpackConfigPath)
53}
54
55const tryReactScripts = () => {
56 // try requiring the file or, if it does not work, try parent folders
57 // maybe it is a monorepo situation
58 const root = findYarnWorkspaceRoot() || process.cwd()
59 debug('trying filename for react scripts from root %s', root)
60 const filename = path.resolve(
61 root,
62 'node_modules',
63 'react-scripts',
64 'config',
65 'webpack.config.js',
66 )
67 return tryLoadingWebpackConfig(filename)
68}
69
70const tryEjectedReactScripts = () => {
71 const webpackConfigPath = path.resolve(
72 process.cwd(),
73 'config',
74 'webpack.config.js',
75 )
76 return tryLoadingWebpackConfig(webpackConfigPath)
77}
78
79/**
80 * Try loading React scripts webpack config using "require" - because maybe
81 * the `react-scripts` were installed in a parent folder (but without using Yarn workspace)
82 */
83const tryWebpackInReactScriptsModule = () => {
84 const webpackConfigModuleName = 'react-scripts/config/webpack.config.js'
85 debug(
86 'trying to require webpack config via path: %s',
87 webpackConfigModuleName,
88 )
89
90 const found = tryLoadingWebpackConfig(webpackConfigModuleName)
91 if (!found) {
92 debug('Could not find react-scripts webpack config')
93 const packageJsonExists = fs.existsSync(
94 path.join(process.cwd(), 'package.json'),
95 )
96 if (!packageJsonExists) {
97 debug('⚠️ react-scripts requires package.json file')
98 debug('We could not find it in % s', process.cwd())
99 }
100 }
101 return found
102}
103
104/**
105 * Tries really hard to find Webpack config file
106 * and load it using development environment name.
107 */
108const getWebpackOptions = () => {
109 debug('get webpack starting from cwd: %s', process.cwd())
110 const webpackOptions =
111 tryReactScripts() ||
112 tryEjectedReactScripts() ||
113 tryVueCLIScripts() ||
114 tryRootProjectWebpack() ||
115 tryWebpackInReactScriptsModule()
116
117 if (!webpackOptions) {
118 // TODO: nice user error message if we can't find
119 // any of the normal webpack configurations
120 debug('could not find webpack options')
121 }
122 return webpackOptions
123}
124
125module.exports = getWebpackOptions