docs: function addExportFrom(ast, moduleSource, defaultExport, namedExport) {
    // Summary:
    //  Add export from source module. Such as export { xxx } from './x';
    let names = [];
  
    if (namedExport) {
      if (typeof namedExport === 'string') {
        names.push(namedExport);
      } else {
        names = names.concat(namedExport);
      }
    }
  
    const changes = [];
    const t = babelTypes;
  
    let targetExportPos = 0;
    let sourceExisted = false;
    traverse(ast, {
      ExportNamedDeclaration(path) {
        const node = path.node;
        targetExportPos = path.node.end + 1;
        if (!node.specifiers || !node.source || node.source.value !== moduleSource) return;
        sourceExisted = true;
        let newNames = [];
        const alreadyHaveDefaultExport = !!_.find(
          node.specifiers,
          s => _.get(s, 'local.name') === 'default',
        );
        if (defaultExport && !alreadyHaveDefaultExport) newNames.push(defaultExport);
  
        newNames = newNames.concat(names);
  
        // only add names which don't exist
        newNames = newNames.filter(
          n =>
            !_.find(
              node.specifiers,
              s => (_.get(s, 'exported.name') || _.get(s, 'local.name')) === n,
            ),
        );
  
        if (newNames.length > 0) {
          const newSpecifiers = [].concat(node.specifiers);
          newNames.forEach(n => {
            const local = t.identifier(n);
            const exported = local; // TODO: doesn't support local alias.
            if (n === defaultExport) {
              newSpecifiers.unshift(t.exportSpecifier(t.identifier('default'), exported));
            } else {
              newSpecifiers.push(t.exportSpecifier(local, exported));
            }
          });
  
          const newNode = Object.assign({}, node, { specifiers: newSpecifiers });
          const newCode = generate(newNode, ast._filePath);
          changes.push({
            start: node.start,
            end: node.end,
            replacement: newCode,
          });
        }
      },
    });
  
    if (changes.length === 0 && !sourceExisted) {
      const specifiers = [];
      if (defaultExport) {
        specifiers.push(t.exportSpecifier(t.identifier('default'), t.identifier(defaultExport)));
      }
  
      names.forEach(n => {
        const local = t.identifier(n);
        const exported = local;
        specifiers.push(t.exportSpecifier(local, exported));
      });
  
      const node = t.ExportNamedDeclaration(null, specifiers, t.stringLiteral(moduleSource));
      const code = generate(node, ast._filePath);
      changes.push({
        start: targetExportPos,
        end: targetExportPos,
        replacement: `${code}\n`,
      });
    }
  
    return changes;
  }