async watch(path, asset) { if (!this.watcher) { return; } path = await fs.realpath(path); if (!this.watchedAssets.has(path)) { this.watcher.watch(path); this.watchedAssets.set(path, new Set()); } this.watchedAssets.get(path).add(asset); }
async unwatch(path, asset) { path = await fs.realpath(path); if (!this.watchedAssets.has(path)) { return; } let watched = this.watchedAssets.get(path); watched.delete(asset); if (watched.size === 0) { this.watchedAssets.delete(path); this.watcher.unwatch(path); } }
async readPackage(dir) { let file = path.join(dir, 'package.json'); if (this.packageCache.has(file)) { return this.packageCache.get(file); } let json = await fs.readFile(file, 'utf8'); let pkg = JSON.parse(json); pkg.pkgfile = file; pkg.pkgdir = dir; // If the package has a `source` field, check if it is behind a symlink. // If so, we treat the module as source code rather than a pre-compiled module. if (pkg.source) { let realpath = await fs.realpath(file); if (realpath === file) { delete pkg.source; } } this.packageCache.set(file, pkg); return pkg; }
async function getBabelConfig(asset) { // Consider the module source code rather than precompiled if the resolver // used the `source` field, or it is not in node_modules. let pkg = await asset.getPackage(); let isSource = !!(pkg && pkg.source && (await fs.realpath(asset.name)) !== asset.name) || !asset.name.includes(NODE_MODULES); // Try to resolve a .babelrc file. If one is found, consider the module source code. let babelrc = await getBabelRc(asset, isSource); isSource = isSource || !!babelrc; let envConfig = await getEnvConfig(asset, isSource); let jsxConfig = await getJSXConfig(asset, isSource); let flowConfig = getFlowConfig(asset, isSource); if (babelrc && envConfig) { // Filter out presets that are already applied by @babel/preset-env if (Array.isArray(babelrc.config.presets)) { babelrc.config.presets = babelrc.config.presets.filter(preset => { return !ENV_PRESETS[getPluginName(preset)]; }); } // Filter out plugins that are already applied by @babel/preset-env if (Array.isArray(babelrc.config.plugins)) { babelrc.config.plugins = babelrc.config.plugins.filter(plugin => { return !ENV_PLUGINS[getPluginName(plugin)]; }); } } let result = {}; mergeConfigs(result, babelrc); mergeConfigs(result, envConfig); // Add JSX config if it isn't already specified in the babelrc let hasReact = babelrc && (hasPlugin(babelrc.config.presets, [ 'react', '@babel/react', '@babel/preset-react' ]) || hasPlugin(babelrc.config.plugins, [ 'transform-react-jsx', '@babel/transform-react-jsx', '@babel/plugin-transform-react-jsx' ])); if (!hasReact) { mergeConfigs(result, jsxConfig); } // Add Flow stripping config if it isn't already specified in the babelrc let hasFlow = babelrc && hasPlugin(babelrc.config.plugins, [ 'transform-flow-strip-types', '@babel/transform-flow-strip-types', '@babel/plugin-transform-flow-strip-types' ]); if (!hasFlow) { mergeConfigs(result, flowConfig); } return result; }