config.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.defaultDefines = exports.resolveConfig = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const fs_extra_1 = __importDefault(require("fs-extra"));
  9. const chalk_1 = __importDefault(require("chalk"));
  10. const dotenv_1 = __importDefault(require("dotenv"));
  11. const dotenv_expand_1 = __importDefault(require("dotenv-expand"));
  12. const buildPluginEsbuild_1 = require("./build/buildPluginEsbuild");
  13. const resolver_1 = require("./resolver");
  14. const utils_1 = require("./utils");
  15. const debug = require('debug')('vite:config');
  16. async function resolveConfig(mode, configPath) {
  17. const start = Date.now();
  18. const cwd = process.cwd();
  19. let config;
  20. let resolvedPath;
  21. let isTS = false;
  22. if (configPath) {
  23. resolvedPath = path_1.default.resolve(cwd, configPath);
  24. }
  25. else {
  26. const jsConfigPath = path_1.default.resolve(cwd, 'vite.config.js');
  27. if (fs_extra_1.default.existsSync(jsConfigPath)) {
  28. resolvedPath = jsConfigPath;
  29. }
  30. else {
  31. const tsConfigPath = path_1.default.resolve(cwd, 'vite.config.ts');
  32. if (fs_extra_1.default.existsSync(tsConfigPath)) {
  33. isTS = true;
  34. resolvedPath = tsConfigPath;
  35. }
  36. }
  37. }
  38. if (!resolvedPath) {
  39. // load environment variables
  40. return {
  41. env: loadEnv(mode, cwd)
  42. };
  43. }
  44. try {
  45. if (!isTS) {
  46. try {
  47. config = require(resolvedPath);
  48. }
  49. catch (e) {
  50. if (!/Cannot use import statement|Unexpected token 'export'|Must use import to load ES Module/.test(e.message)) {
  51. throw e;
  52. }
  53. }
  54. }
  55. if (!config) {
  56. // 2. if we reach here, the file is ts or using es import syntax, or
  57. // the user has type: "module" in their package.json (#917)
  58. // transpile es import syntax to require syntax using rollup.
  59. const rollup = require('rollup');
  60. const esbuildPlugin = await buildPluginEsbuild_1.createEsbuildPlugin({});
  61. const esbuildRenderChunkPlugin = buildPluginEsbuild_1.createEsbuildRenderChunkPlugin('es2019', false);
  62. // use node-resolve to support .ts files
  63. const nodeResolve = require('@rollup/plugin-node-resolve').nodeResolve({
  64. extensions: resolver_1.supportedExts
  65. });
  66. const bundle = await rollup.rollup({
  67. external: (id) => (id[0] !== '.' && !path_1.default.isAbsolute(id)) ||
  68. id.slice(-5, id.length) === '.json',
  69. input: resolvedPath,
  70. treeshake: false,
  71. plugins: [esbuildPlugin, nodeResolve, esbuildRenderChunkPlugin]
  72. });
  73. const { output: [{ code }] } = await bundle.generate({
  74. exports: 'named',
  75. format: 'cjs'
  76. });
  77. config = await loadConfigFromBundledFile(resolvedPath, code);
  78. }
  79. if (typeof config === 'function') {
  80. config = config(mode);
  81. }
  82. // normalize config root to absolute
  83. if (config.root && !path_1.default.isAbsolute(config.root)) {
  84. config.root = path_1.default.resolve(path_1.default.dirname(resolvedPath), config.root);
  85. }
  86. if (typeof config.vueTransformAssetUrls === 'object') {
  87. config.vueTransformAssetUrls = normalizeAssetUrlOptions(config.vueTransformAssetUrls);
  88. }
  89. // resolve plugins
  90. if (config.plugins) {
  91. for (const plugin of config.plugins) {
  92. config = resolvePlugin(config, plugin);
  93. }
  94. }
  95. config.env = {
  96. ...config.env,
  97. ...loadEnv(mode, config.root || cwd)
  98. };
  99. debug(`config resolved in ${Date.now() - start}ms`);
  100. config.__path = resolvedPath;
  101. return config;
  102. }
  103. catch (e) {
  104. console.error(chalk_1.default.red(`[vite] failed to load config from ${resolvedPath}:`));
  105. console.error(e);
  106. process.exit(1);
  107. }
  108. }
  109. exports.resolveConfig = resolveConfig;
  110. async function loadConfigFromBundledFile(fileName, bundledCode) {
  111. const extension = path_1.default.extname(fileName);
  112. const defaultLoader = require.extensions[extension];
  113. require.extensions[extension] = (module, filename) => {
  114. if (filename === fileName) {
  115. ;
  116. module._compile(bundledCode, filename);
  117. }
  118. else {
  119. defaultLoader(module, filename);
  120. }
  121. };
  122. delete require.cache[fileName];
  123. const raw = require(fileName);
  124. const config = raw.__esModule ? raw.default : raw;
  125. require.extensions[extension] = defaultLoader;
  126. return config;
  127. }
  128. function resolvePlugin(config, plugin) {
  129. return {
  130. ...config,
  131. ...plugin,
  132. alias: {
  133. ...plugin.alias,
  134. ...config.alias
  135. },
  136. define: {
  137. ...plugin.define,
  138. ...config.define
  139. },
  140. transforms: [...(config.transforms || []), ...(plugin.transforms || [])],
  141. indexHtmlTransforms: [
  142. ...(config.indexHtmlTransforms || []),
  143. ...(plugin.indexHtmlTransforms || [])
  144. ],
  145. resolvers: [...(config.resolvers || []), ...(plugin.resolvers || [])],
  146. configureServer: [].concat(config.configureServer || [], plugin.configureServer || []),
  147. configureBuild: [].concat(config.configureBuild || [], plugin.configureBuild || []),
  148. vueCompilerOptions: {
  149. ...config.vueCompilerOptions,
  150. ...plugin.vueCompilerOptions
  151. },
  152. vueTransformAssetUrls: mergeAssetUrlOptions(config.vueTransformAssetUrls, plugin.vueTransformAssetUrls),
  153. vueTemplatePreprocessOptions: {
  154. ...config.vueTemplatePreprocessOptions,
  155. ...plugin.vueTemplatePreprocessOptions
  156. },
  157. vueCustomBlockTransforms: {
  158. ...config.vueCustomBlockTransforms,
  159. ...plugin.vueCustomBlockTransforms
  160. },
  161. rollupInputOptions: mergeObjectOptions(config.rollupInputOptions, plugin.rollupInputOptions),
  162. rollupOutputOptions: mergeObjectOptions(config.rollupOutputOptions, plugin.rollupOutputOptions),
  163. enableRollupPluginVue: config.enableRollupPluginVue || plugin.enableRollupPluginVue
  164. };
  165. }
  166. function mergeAssetUrlOptions(to, from) {
  167. if (from === true) {
  168. return to;
  169. }
  170. if (from === false) {
  171. return from;
  172. }
  173. if (typeof to === 'boolean') {
  174. return from || to;
  175. }
  176. return {
  177. ...normalizeAssetUrlOptions(to),
  178. ...normalizeAssetUrlOptions(from)
  179. };
  180. }
  181. function normalizeAssetUrlOptions(o) {
  182. if (o && Object.keys(o).some((key) => Array.isArray(o[key]))) {
  183. return {
  184. tags: o
  185. };
  186. }
  187. else {
  188. return o;
  189. }
  190. }
  191. function mergeObjectOptions(to, from) {
  192. if (!to)
  193. return from;
  194. if (!from)
  195. return to;
  196. const res = { ...to };
  197. for (const key in from) {
  198. const existing = res[key];
  199. const toMerge = from[key];
  200. if (Array.isArray(existing) || Array.isArray(toMerge)) {
  201. res[key] = [].concat(existing, toMerge).filter(Boolean);
  202. }
  203. else {
  204. res[key] = toMerge;
  205. }
  206. }
  207. return res;
  208. }
  209. function loadEnv(mode, root) {
  210. if (mode === 'local') {
  211. throw new Error(`"local" cannot be used as a mode name because it conflicts with ` +
  212. `the .local postfix for .env files.`);
  213. }
  214. debug(`env mode: ${mode}`);
  215. const clientEnv = {};
  216. const envFiles = [
  217. /** mode local file */ `.env.${mode}.local`,
  218. /** mode file */ `.env.${mode}`,
  219. /** local file */ `.env.local`,
  220. /** default file */ `.env`
  221. ];
  222. for (const file of envFiles) {
  223. const path = utils_1.lookupFile(root, [file], true);
  224. if (path) {
  225. // NOTE: this mutates process.env
  226. const { parsed, error } = dotenv_1.default.config({
  227. debug: !!process.env.DEBUG || undefined,
  228. path
  229. });
  230. if (!parsed) {
  231. throw error;
  232. }
  233. // NOTE: this mutates process.env
  234. dotenv_expand_1.default({ parsed });
  235. // set NODE_ENV under a different key so that we know this is set from
  236. // vite-loaded .env files. Some users may have default NODE_ENV set in
  237. // their system.
  238. if (parsed.NODE_ENV) {
  239. process.env.VITE_ENV = parsed.NODE_ENV;
  240. }
  241. // only keys that start with VITE_ are exposed.
  242. for (const [key, value] of Object.entries(parsed)) {
  243. if (key.startsWith(`VITE_`)) {
  244. clientEnv[key] = value;
  245. }
  246. }
  247. }
  248. }
  249. debug(`env: %O`, clientEnv);
  250. return clientEnv;
  251. }
  252. // TODO move this into Vue plugin when we extract it
  253. exports.defaultDefines = {
  254. __VUE_OPTIONS_API__: true,
  255. __VUE_PROD_DEVTOOLS__: false
  256. };
  257. //# sourceMappingURL=config.js.map