Example #1
0
  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);
  }
Example #2
0
  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);
    }
  }
Example #3
0
  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;
  }
Example #4
0
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;
}