const { join } = require('path'); const { writeFileSync, mkdirSync, existsSync } = require('fs'); const rimraf = require('rimraf'); const serveStatic = require('serve-static'); const { resolve } = require('path'); const { portfinder, chalk, delay, createDebug, chokidar, signale, glob } = require('@umijs/utils'); const argv = require('./argv'); const setup = require('./middlewares/frontendMiddleware'); const pkg = require('../package.json'); const config = require('../config/config'); const mockMiddewares = require('./mock'); const emitter = require('./event'); const Server = require('./server'); const debug = createDebug('preset-build-in:proxy:createMiddleware'); // const proxyConfig = require('../config/proxy'); const loadDotEnv = require('./utils/loadDotEnv'); const { getSchema } = require('./openapi'); const cleanRequireCache = require('./utils/cleanRequireCache'); (async () => { const defaultPort = process.env.PORT || argv.port || (config && config.devServer && config.devServer.port); const port = await portfinder.getPortPromise({ port: defaultPort ? parseInt(String(defaultPort), 10) : 8080, }); const homename = process.env.HOST || (config && config.devServer && config.devServer.host) || '127.0.0.1'; console.log(chalk.cyan('Starting the development server...')); // process.send && process.send({ type: 'UPDATE_PORT', port }); const isHTTPS = process.env.HTTPS || (argv && argv.https); await delay(500); const absNodeModulesPath = `${process.cwd()}/node_modules`; const openAPIFilesPath = join(absNodeModulesPath, 'civ_open_api'); const loadEnv = () => { const basePath = join(process.cwd(), '.env'); const localPath = `${basePath}.local`; loadDotEnv(basePath); loadDotEnv(localPath); }; loadEnv(); // const absNodeModulesPath = cwd + '/node_modules'; try { if (existsSync(openAPIFilesPath)) { rimraf.sync(openAPIFilesPath); } mkdirSync(join(openAPIFilesPath)); } catch (error) { console.error(error); } const server = new Server({ compress: true, https: !!isHTTPS, headers: { 'access-control-allow-origin': '*', }, port, beforeMiddlewares: [ (config.mock || process.env.MOCK !== 'none') && mockMiddewares, ], afterMiddlewares: [serveStatic(openAPIFilesPath)], proxy: config.proxy, ...(config.devServer || {}), }); setup( server.app, { outputPath: resolve(process.cwd(), pkg.name.toLocaleLowerCase()), publicPath: `/${pkg.name.toLocaleLowerCase()}`, }, config, { port, homename, }, ); // proxy config 热更新 const ignore = [ // ignore mock files under node_modules 'node_modules/**' ]; const cwd = process.cwd(); const proxyWatcherPaths = [ ...(glob.sync('config/proxy.js', { cwd, ignore, }) || []), ...(glob.sync('**/proxy.js', { cwd, ignore, }) || []), ...(glob.sync('.env', { cwd, ignore, }) || []), ...(glob.sync('.env.local', { cwd, ignore, }) || []) ]; const watcher = chokidar.watch(proxyWatcherPaths, { ignoreInitial: true, }); const errors = []; watcher.on('ready', () => debug('Initial scan complete. Ready for changes')).on('all', async (event, file) => { debug(`[${event}] ${file}, reload proxy config`);`` errors.splice(0, errors.length); cleanRequireCache(Array.from(new Set(proxyWatcherPaths))); if (!errors.length) { const hotProxy = require('../config/proxy'); server.setupProxy && server.setupProxy(hotProxy[process.env.NODE_ENV], true); signale.success(`Proxy config parse success`); } }); process.once('SIGINT', async () => { await watcher.close(); }); emitter.on('onDevCompileDone', async () => { try { const openAPIConfig = config.openAPI; if (openAPIConfig && openAPIConfig.schemaPath) { const openAPIJson = await getSchema(openAPIConfig.schemaPath); writeFileSync( join(openAPIFilesPath, 'civ-plugins_openapi.json'), JSON.stringify(openAPIJson, null, 2), ); } } catch (error) { console.error(error); } }); await server.listen({ port, homename, }); })();