text: "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const path_1 = __importDefault(require("path"));
  const fs_1 = require("fs");
  const resolveVue_1 = require("./resolveVue");
  const serverPluginHmr_1 = require("./serverPluginHmr");
  const resolve_from_1 = __importDefault(require("resolve-from"));
  const chalk_1 = __importDefault(require("chalk"));
  async function build({ root = process.cwd(), cdn = !resolveVue_1.resolveVue(root).hasLocalVue } = {}) {
      process.env.NODE_ENV = 'production';
      const start = Date.now();
      // lazy require rollup so that we don't load it when only using the dev server
      // importing it just for the types
      const rollup = require('rollup').rollup;
      const outDir = path_1.default.resolve(root, 'dist');
      const indexPath = path_1.default.resolve(root, 'index.html');
      const scriptRE = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
      const indexContent = await fs_1.promises.readFile(indexPath, 'utf-8');
      const cssFilename = 'style.css';
      // make sure to use the same verison of vue from the CDN.
      const vueVersion = resolveVue_1.resolveVue(root).version;
      const cdnLink = `https://unpkg.com/vue@${vueVersion}/dist/vue.esm-browser.prod.js`;
      const vitePlugin = {
          name: 'vite',
          resolveId(id) {
              if (id.startsWith('/')) {
                  if (id === serverPluginHmr_1.hmrClientPublicPath) {
                      return serverPluginHmr_1.hmrClientPublicPath;
                  }
                  else {
                      return id.startsWith(root) ? id : path_1.default.resolve(root, id.slice(1));
                  }
              }
              else if (id === 'vue') {
                  if (!cdn) {
                      return resolveVue_1.resolveVue(root, true).vue;
                  }
                  else {
                      return {
                          id: cdnLink,
                          external: true
                      };
                  }
              }
          },
          load(id) {
              if (id === serverPluginHmr_1.hmrClientPublicPath) {
                  return `export function hot() {}`;
              }
              else if (id === indexPath) {
                  let script = '';
                  let match;
                  while ((match = scriptRE.exec(indexContent))) {
                      // TODO handle <script type="module" src="..."/>
                      // just add it as an import
                      script += match[1];
                  }
                  return script;
              }
          }
      };
      const styles = new Map();
      const cssExtractPlugin = {
          name: 'vite-css',
          transform(code, id) {
              if (id.endsWith('.css')) {
                  styles.set(id, code);
                  return '/* css extracted by vite */';
              }
          }
      };
      const bundle = await rollup({
          input: path_1.default.resolve(root, 'index.html'),
          preserveEntrySignatures: false,
          plugins: [
              vitePlugin,
              require('rollup-plugin-vue')({
                  // TODO: for now we directly handle pre-processors in rollup-plugin-vue
                  // so that we don't need to install dedicated rollup plugins.
                  // In the future we probably want to still use rollup plugins so that
                  // preprocessors are also supported by importing from js files.
                  preprocessStyles: true,
                  preprocessCustomRequire: (id) => require(resolve_from_1.default(root, id))
                  // TODO proxy cssModules config
              }),
              require('@rollup/plugin-node-resolve')({
                  rootDir: root
              }),
              require('@rollup/plugin-replace')({
                  'process.env.NODE_ENV': '"production"'
              }),
              cssExtractPlugin,
              require('rollup-plugin-terser').terser()
          ]
      });
      const { output } = await bundle.generate({
          dir: outDir,
          format: 'es'
      });
      await fs_1.promises.rmdir(outDir, { recursive: true });
      await fs_1.promises.mkdir(outDir);
      let generatedIndex = indexContent.replace(scriptRE, '').trim();
      // TODO handle public path for injections?
      // this would also affect paths in templates and css.
      // inject css link
      generatedIndex = injectCSS(generatedIndex, cssFilename);
      // write css
      let css = '';
      styles.forEach((s) => {
          css += s;
      });
      const cssFilepath = path_1.default.join(outDir, cssFilename);
      console.log(`write ${chalk_1.default.magenta(path_1.default.relative(process.cwd(), cssFilepath))}`);
      await fs_1.promises.writeFile(cssFilepath, 
      // minify with cssnano
      (await require('postcss')([require('cssnano')]).process(css, {
          from: undefined
      })).css);
      if (cdn) {
          // if not inlining vue, inject cdn link so it can start the fetch early
          generatedIndex = injectScript(generatedIndex, cdnLink);
      }
      // inject chunks
      for (const chunk of output) {
          if (chunk.type === 'chunk') {
              if (chunk.isEntry) {
                  // inject chunk to html
                  generatedIndex = injectScript(generatedIndex, chunk.fileName);
              }
              // write chunk
              const filepath = path_1.default.join(outDir, chunk.fileName);
              console.log(`write ${chalk_1.default.cyan(path_1.default.relative(process.cwd(), filepath))}`);
              await fs_1.promises.writeFile(filepath, chunk.code);
          }
      }
      // write html
      const indexOutPath = path_1.default.join(outDir, 'index.html');
      console.log(`write ${chalk_1.default.green(path_1.default.relative(process.cwd(), indexOutPath))}`);
      await fs_1.promises.writeFile(indexOutPath, generatedIndex);
      console.log(`done in ${((Date.now() - start) / 1000).toFixed(2)}s.`);
  }
  exports.build = build;
  function injectCSS(html, filename) {
      const tag = `<link rel="stylesheet" href="/${filename}">`;
      if (/<\/head>/.test(html)) {
          return html.replace(/<\/head>/, `${tag}\n</head>`);
      }
      else {
          return tag + '\n' + html;
      }
  }
  function injectScript(html, filename) {
      filename = /^https?:\/\//.test(filename) ? filename : `/${filename}`;
      const tag = `<script type="module" src="${filename}"></script>`;
      if (/<\/body>/.test(html)) {
          return html.replace(/<\/body>/, `${tag}\n</body>`);
      }
      else {
          return html + '\n' + tag;
      }
  }
  