text: import path from "path";
  import alias from "rollup-plugin-alias";
  import { plugin as analyze } from "rollup-plugin-analyzer";
  import commonjs from "rollup-plugin-commonjs";
  import globals from "rollup-plugin-node-globals";
  import nodeResolve from "rollup-plugin-node-resolve";
  import typescriptPlugin from "rollup-plugin-typescript2";
  import { createFilter } from "rollup-pluginutils";
  import typescript from "typescript";
  
  const mockPath = path.join(__dirname, "js", "mock_builtin.js");
  const tsconfig = path.join(__dirname, "tsconfig.json");
  const typescriptPath = `${
    process.env.BASEPATH
  }/third_party/node_modules/typescript/lib/typescript.js`;
  
  // We will allow generated modules to be resolvable by TypeScript based on
  // the current build path
  const tsconfigOverride = {
    compilerOptions: {
      paths: {
        "*": ["*", path.join(process.cwd(), "*")]
      }
    }
  };
  
  // when the build path is not a child of the root of the project path
  // TypeScript will output resources following the same path structure,
  // `BASEPATH` will be a relative path to the root of the source project which
  // we can use to determine what TypeScript would have output
  const basePathParts = process.env.BASEPATH.split("/");
  while (basePathParts[0] === "..") {
    basePathParts.shift();
  }
  
  // this is a rollup plugin which will look for imports ending with `!string` and resolve
  // them with a module that will inline the contents of the file as a string.  Needed to
  // support `js/assets.ts`.
  function strings({ include, exclude } = {}) {
    if (!include) {
      throw new Error("include option must be passed");
    }
  
    const filter = createFilter(include, exclude);
  
    return {
      name: "strings",
  
      /**
       * @param {string} importee
       */
      resolveId(importee) {
        if (importee.endsWith("!string")) {
          // strip the `!string` from `importee`
          importee = importee.slice(0, importee.lastIndexOf("!string"));
          if (!importee.startsWith("gen/")) {
            // this is a static asset which is located relative to the root of the source project
            return path.resolve(path.join(process.env.BASEPATH, importee));
          }
          // ignoring the first part, which is "gen"
          const [, ...importeeParts] = importee.split("/");
          // generated assets will be output by TypeScript relative between the build path and the
          // root of the project.  For example on Travis, the project path is:
          //     /home/travis/build/denoland/deno/
          // and the build path is:
          //     /home/travis/out/Default/
          // TypeScript will then output `globals.d.ts` from `js/globals.ts` to:
          //    /home/travis/out/Default/gen/build/denoland/deno/js/globals.d.ts
          // therefore we need to insert any non relative BASEPATH parts into
          // the final module ID
          return path.resolve(
            path.join(process.cwd(), "gen", ...basePathParts, ...importeeParts)
          );
        }
      },
  
      /**
       * @param {any} code
       * @param {string} id
       */
      transform(code, id) {
        if (filter(id)) {
          return {
            code: `export default ${JSON.stringify(code)};`,
            map: { mappings: "" }
          };
        }
      }
    };
  }
  
  // This plugin resolves at bundle time any generated resources that are
  // in the build path under `gen` and specified with a MID starting with `gen/`.
  // The plugin assumes that the MID needs to have the `.ts` extension appended.
  function resolveGenerated() {
    return {
      name: "resolve-msg-generated",
      resolveId(importee) {
        if (importee.startsWith("gen/")) {
          const resolved = path.resolve(
            path.join(process.cwd(), `${importee}.ts`)
          );
          return resolved;
        }
      }
    };
  }
  
  export default function makeConfig(commandOptions) {
    return {
      output: {
        format: "iife",
        name: "denoMain",
        sourcemap: true
      },
  
      plugins: [
        // would prefer to use `rollup-plugin-virtual` to inject the empty module, but there
        // is an issue with `rollup-plugin-commonjs` which causes errors when using the
        // virtual plugin (see: rollup/rollup-plugin-commonjs#315), this means we have to use
        // a physical module to substitute
        alias({
          fs: mockPath,
          path: mockPath,
          os: mockPath,
          crypto: mockPath,
          buffer: mockPath,
          module: mockPath
        }),
  
        // Provides inlining of file contents for `js/assets.ts`
        strings({
          include: [
            "*.d.ts",
            `${__dirname}/**/*.d.ts`,
            `${process.cwd()}/**/*.d.ts`
          ]
        }),
  
        // Resolves any resources that have been generated at build time
        resolveGenerated(),
  
        // Allows rollup to resolve modules based on Node.js resolution
        nodeResolve({
          jsnext: true,
          main: true
        }),
  
        // Allows rollup to import CommonJS modules
        commonjs({
          namedExports: {
            // Static analysis of `typescript.js` does detect the exports properly, therefore
            // rollup requires them to be explicitly defined to avoid generating warnings
            [typescriptPath]: [
              "createLanguageService",
              "formatDiagnosticsWithColorAndContext",
              "ModuleKind",
              "ScriptSnapshot",
              "ScriptTarget",
              "version"
            ]
          }
        }),
  
        typescriptPlugin({
          // The build script is invoked from `out/:target` so passing an absolute file path is needed
          tsconfig,
  
          // This provides any overrides to the `tsconfig.json` that are needed to bundle
          tsconfigOverride,
  
          // This provides the locally configured version of TypeScript instead of the plugins
          // default version
          typescript,
  
          // By default, the include path only includes the cwd and below, need to include the root of the project
          // and build path to be passed to this plugin.  This is different front tsconfig.json include
          include: ["*.ts", `${__dirname}/**/*.ts`, `${process.cwd()}/**/*.ts`],
  
          // d.ts files are not bundled and by default like include, it only includes the cwd and below
          exclude: [
            "*.d.ts",
            `${__dirname}/**/*.d.ts`,
            `${process.cwd()}/**/*.d.ts`
          ]
        }),
  
        // Provide some concise information about the bundle
        analyze({
          skipFormatted: true,
          onAnalysis({
            bundleSize,
            bundleOrigSize,
            bundleReduction,
            moduleCount
          }) {
            if (!commandOptions.silent) {
              console.log(
                `Bundle size: ${Math.round((bundleSize / 1000000) * 100) / 100}Mb`
              );
              console.log(
                `Original size: ${Math.round((bundleOrigSize / 1000000) * 100) /
                  100}Mb`
              );
              console.log(`Reduction: ${bundleReduction}%`);
              console.log(`Module count: ${moduleCount}`);
            }
          }
        }),
  
        // source-map-support, which is required by TypeScript to support source maps, requires Node.js Buffer
        // implementation.  This needs to come at the end of the plugins because of the impact it has on
        // the existing runtime environment, which breaks other plugins and features of the bundler.
        globals()
      ]
    };
  }
  