vite#ResolvedConfig TypeScript Examples

The following examples show how to use vite#ResolvedConfig. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From vite-ssr with MIT License 6 votes vote down vote up
async function generatePackageJson(
  viteConfig: ResolvedConfig,
  clientBuildOptions: InlineConfig,
  serverBuildOptions: NonNullable<BuildOptions['serverOptions']>
) {
  if (serverBuildOptions.packageJson === false) return

  const outputFile = (
    serverBuildOptions.build?.rollupOptions?.output as OutputOptions
  )?.file

  const ssrOutput = path.parse(
    outputFile ||
      ((viteConfig.build?.ssr || serverBuildOptions.build?.ssr) as string)
  )

  const moduleFormat =
    (viteConfig.build?.rollupOptions?.output as OutputOptions)?.format ||
    (serverBuildOptions.build?.rollupOptions?.output as OutputOptions)?.format

  const packageJson = {
    main: outputFile ? ssrOutput.base : ssrOutput.name + '.js',
    type: /^esm?$/i.test(moduleFormat || '') ? 'module' : 'commonjs',
    ssr: {
      // This can be used later to serve static assets
      assets: (
        await fs.readdir(clientBuildOptions.build?.outDir as string)
      ).filter((file) => !/(index\.html|manifest\.json)$/i.test(file)),
    },
    ...(serverBuildOptions.packageJson || {}),
  }

  await fs.writeFile(
    path.join(serverBuildOptions.build?.outDir as string, 'package.json'),
    JSON.stringify(packageJson, null, 2),
    'utf-8'
  )
}
Example #2
Source File: config.ts    From vite-ssr with MIT License 6 votes vote down vote up
export async function getEntryPoint(
  config?: ResolvedConfig,
  indexHtml?: string
) {
  if (!config) {
    config = await resolveViteConfig()
  }

  if (!indexHtml) {
    indexHtml = await fs.promises.readFile(
      getPluginOptions(config).input || path.resolve(config.root, INDEX_HTML),
      'utf-8'
    )
  }

  const matches = indexHtml
    .substr(indexHtml.lastIndexOf('script type="module"'))
    .match(/src="(.*)">/i)

  const entryFile = matches?.[1] || 'src/main'

  return path.join(config.root, entryFile)
}
Example #3
Source File: injection.ts    From vite-plugin-vue-i18n with MIT License 6 votes vote down vote up
function generateCode(
  values: InjectionValues,
  indentifier: string,
  id: string,
  config: ResolvedConfig
): string {
  const injectionCodes = ['']
  Object.keys(values).forEach(key => {
    const code = values[key]
    if (isFunction(code)) {
      injectionCodes.push(
        `${indentifier}.${key} = ${JSON.stringify(code(id, config))}`
      )
    } else {
      injectionCodes.push(`${indentifier}.${key} = ${toCode(code)}`)
    }
  })

  const ret = injectionCodes.join('\n')
  return ret.length > 0 ? `\n${ret}\n` : ''
}
Example #4
Source File: injection.ts    From vite-plugin-vue-i18n with MIT License 6 votes vote down vote up
export default function IntlifyVue(values: InjectionValues = {}): Plugin {
  let config: ResolvedConfig | null = null

  return {
    enforce: 'post',
    name: 'vite-plugin-vue-i18n:intlify-vue',
    configResolved(_config: ResolvedConfig) {
      config = _config
    },
    transform(code: string, id: string) {
      debug('transform', id)
      if (id.endsWith('.vue')) {
        const magic = new MagicString(code)
        const indentifier = '_sfc_main'
        const index = code.indexOf(`export default ${indentifier}`)
        magic.appendLeft(index, generateCode(values, indentifier, id, config!))
        return {
          code: magic.toString(),
          map: magic.generateMap()
        }
      }
    }
  }
}
Example #5
Source File: postcss.ts    From vanilla-extract with MIT License 6 votes vote down vote up
resolvePostcssConfig = async (
  config: ResolvedConfig,
): Promise<PostCSSConfigResult | null> => {
  // inline postcss config via vite config
  const inlineOptions = config.css?.postcss;
  const inlineOptionsIsString = typeof inlineOptions === 'string';

  if (inlineOptions && !inlineOptionsIsString) {
    const options = { ...inlineOptions };

    delete options.plugins;
    return {
      options,
      plugins: inlineOptions.plugins || [],
    };
  } else {
    try {
      const searchPath =
        typeof inlineOptions === 'string' ? inlineOptions : config.root;

      const postCssConfig = await (
        await import('postcss-load-config')
      ).default({}, searchPath);

      return {
        options: postCssConfig.options,
        // @ts-expect-error - The postcssrc options don't agree with real postcss, but it should be ok
        plugins: postCssConfig.plugins,
      };
    } catch (e: any) {
      if (!/No PostCSS Config found/.test(e.message)) {
        throw e;
      }
      return null;
    }
  }
}
Example #6
Source File: workerMiddleware.ts    From vite-plugin-monaco-editor with MIT License 6 votes vote down vote up
export function workerMiddleware(
  middlewares: Connect.Server,
  config: ResolvedConfig,
  options: IMonacoEditorOpts
): void {
  const works = getWorks(options);
  // clear cacheDir

  if (fs.existsSync(cacheDir)) {
    fs.rmdirSync(cacheDir, { recursive: true, force: true } as fs.RmDirOptions);
  }

  for (const work of works) {
    console.log(config.base + options.publicPath + '/' + getFilenameByEntry(work.entry))
    middlewares.use(
      config.base + options.publicPath + '/' + getFilenameByEntry(work.entry),
      function (req, res, next) {
        if (!fs.existsSync(cacheDir + getFilenameByEntry(work.entry))) {
          esbuild.buildSync({
            entryPoints: [resolveMonacoPath(work.entry)],
            bundle: true,
            outfile: cacheDir + getFilenameByEntry(work.entry),
          });
        }
        const contentBuffer = fs.readFileSync(cacheDir + getFilenameByEntry(work.entry));
        res.setHeader('Content-Type', 'text/javascript');
        res.end(contentBuffer);
      }
    );
  }
}
Example #7
Source File: index.ts    From convue with MIT License 6 votes vote down vote up
export default function HtmlPlugin(userOptions: Options = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let options: Options = userOptions;
  let title: string;

  return {
    name: 'vite-plugin-html',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      if (options.head && options.head.title) {
        title = options.head.title;
      } else {
        const packageJson = JSON.parse(
          fs.readFileSync(normalizePath(resolve(config.root, 'package.json')), 'utf-8')
        );
        title = packageJson.name;
        debug('title', title);
      }
    },
    transformIndexHtml(html) {
      return html
        .replace(/<!-- TITLE -->/, title)
        .replace(/<!-- HEAD -->/, genarateHeadElements(options))
        .replace(/<!-- APP -->/, genrateLoading(options));
    },
  };
}
Example #8
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
function routePlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let filesPath: string[] = [];
  let generatedStores: any[] | null | undefined;

  const options: ResolvedOptions = resolveOptions(userOptions);

  return {
    name: 'vite-plugin-store',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      options.storeDirPath = normalizePath(resolve(config.root, options.dir));
      debug('storeDirPath', options.storeDirPath);
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        debug('Loading files...');

        filesPath = await getStoresPath(options);

        debug('FilesPath: %O', filesPath);

        if (!generatedStores) generatedStores = generateStores(filesPath, options);

        debug('Components: %O', generatedStores);

        const clientCode = generateClientCode(generatedStores);

        debug('Client code: %O', clientCode)

        return clientCode;
      }
    },
    async handleHotUpdate({ file, server }) {
      const extensionsRE = new RegExp(`\\.(${options.extensions.join('|')})$`);
      const storeDir = options.dir;
      const storeDirPath = options.storeDirPath;
      // Handle pages HMR
      if (
        (file.startsWith(storeDirPath) || file.startsWith(storeDirPath)) &&
        extensionsRE.test(file)
      ) {
        let needReload = false;

        // HMR on new file created
        // Otherwise, handle HMR from custom block
        if (file.includes(storeDir)) {
          if (
            !filesPath.includes(file.replace(`${storeDirPath}/`, ''))
          ) {
            generatedStores = null;
            needReload = true;
          }
        }

        if (needReload) {
          const { moduleGraph } = server;
          const module = moduleGraph.getModuleById(ID);

          debug('Reload for file: %s', file.replace(options.root, ''));

          return [module] as ModuleNode[];
        }
      }
    },
  };
}
Example #9
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
function routePlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let filesPath: string[] = [];
  let generatedPlugins: any[] | null | undefined;

  const options: ResolvedOptions = resolveOptions(userOptions);

  return {
    name: 'vite-plugin-store',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      options.pluginsDirPath = normalizePath(resolve(config.root, options.dir));
      debug('pluginsDirPath', options.pluginsDirPath);
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        debug('Loading files...');

        filesPath = await getStoresPath(options);

        debug('FilesPath: %O', filesPath);

        if (!generatedPlugins) generatedPlugins = generatePlugins(filesPath, options);

        debug('Components: %O', generatedPlugins);

        const clientCode = generateClientCode(generatedPlugins);

        debug('Client code: %O', clientCode)

        return clientCode;
      }
    },
    async handleHotUpdate({ file, server }) {
      const extensionsRE = new RegExp(`\\.(${options.extensions.join('|')})$`);
      const storeDir = options.dir;
      const pluginsDirPath = options.pluginsDirPath;
      // Handle pages HMR
      if (
        (file.startsWith(pluginsDirPath) || file.startsWith(pluginsDirPath)) &&
        extensionsRE.test(file)
      ) {
        let needReload = false;

        // HMR on new file created
        // Otherwise, handle HMR from custom block
        if (file.includes(storeDir)) {
          if (
            !filesPath.includes(file.replace(`${pluginsDirPath}/`, ''))
          ) {
            generatedPlugins = null;
            needReload = true;
          }
        }

        if (needReload) {
          const { moduleGraph } = server;
          const module = moduleGraph.getModuleById(ID);

          debug('Reload for file: %s', file.replace(options.root, ''));

          return [module] as ModuleNode[];
        }
      }
    },
  };
}
Example #10
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
export default function PackagesPlugin(userOptions: Options = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let options: Options = userOptions;
  const styles: string[] = options.styles || [];
  const modules: string[] = options.modules || [];

  return {
    name: 'vite-plugin-package',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        return `
          import router from 'pages-generated';
          import globalComponent from 'components-generated';
          import store from 'store-generated';
          import plugin from 'plugin-generated';
          import i18n from 'locale-generated';
          ${modules.map((module, index) => `import _package_${index} from '${module}'`).join(';\n')}
          ${styles.map(style => `import '${style}'`).join(';\n')}

          const install = (app) => {
            app.use(i18n);
            window.t = window.$t = window._t = i18n.global.t;
            window.i18n = i18n;
            app.config.globalProperties = {
              ...app.config.globalProperties,
              $t: i18n.global.t,
            };
            app.use(router);
            app.use(store);
            app.use(plugin);
            app.use(globalComponent);
            ${modules.map((_module, index) => `app.use(_package_${index})`).join(';\n')}
            window.__APP__ = app;
          };

          export default {
            install
          };
        `;
      }
    },
  };
}
Example #11
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
function routePlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let filesPath: string[] = [];
  let generatedLocales: any[] | null | undefined;

  const options: ResolvedOptions = resolveOptions(userOptions);

  if (options.useCookie === true) {
    options.useCookie = {
      cookieKey: 'i18n',
      expires: 365,
    }
  }

  return {
    name: 'vite-plugin-store',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      options.localesDirPath = normalizePath(resolve(config.root, options.dir));
      debug('localesDirPath', options.localesDirPath);
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        debug('Loading files...');

        filesPath = await getLocalesPath(options);

        debug('FilesPath: %O', filesPath);

        if (!generatedLocales) generatedLocales = generateLocales(filesPath, options);

        debug('Components: %O', generatedLocales);

        const clientCode = generateClientCode(generatedLocales, options);

        debug('Client code: %O', clientCode)

        return clientCode;
      }
    },
    async handleHotUpdate({ file, server }) {
      const extensionsRE = new RegExp(`\\.(${options.extensions.join('|')})$`);
      const storeDir = options.dir;
      const localesDirPath = options.localesDirPath;
      // Handle pages HMR
      if (
        (file.startsWith(localesDirPath) || file.startsWith(localesDirPath)) &&
        extensionsRE.test(file)
      ) {
        let needReload = false;

        // HMR on new file created
        // Otherwise, handle HMR from custom block
        if (file.includes(storeDir)) {
          if (
            !filesPath.includes(file.replace(`${localesDirPath}/`, ''))
          ) {
            generatedLocales = null;
            needReload = true;
          }
        }

        if (needReload) {
          const { moduleGraph } = server;
          const module = moduleGraph.getModuleById(ID);

          debug('Reload for file: %s', file.replace(options.root, ''));

          return [module] as ModuleNode[];
        }
      }
    },
  };
}
Example #12
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
function layoutPlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined

  const options: ResolvedOptions = resolveOptions(userOptions)

  if (options.useCookie === true) {
    options.useCookie = {
      cookieKey: 'i18n',
      expires: 365,
    }
  }

  return {
    name: 'vite-plugin-layouts',
    enforce: 'pre',
    configResolved(_config) {
      config = _config
      options.root = config.root
    },
    resolveId(id) {
      if (id === ID)
        return ID
    },
    async load(id) {
      if (id === ID) {
        const layoutsDirPath = normalizePath(resolve(options.root, options.dir))
        debug('Loading Layout Dir: %O', layoutsDirPath)

        const files = await getFilesFromPath(layoutsDirPath, options)

        const importCode = getImportCode(files, options)

        const clientCode = getClientCode(importCode, options)

        debug('Client code: %O', clientCode)

        return clientCode
      }
    },
  }
}
Example #13
Source File: index.ts    From convue with MIT License 5 votes vote down vote up
function routePlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let filesPath: string[] = [];
  let generatedComponents: any[] | null | undefined;

  const options: ResolvedOptions = resolveOptions(userOptions);

  return {
    name: 'vite-plugin-components',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      options.componentsDirPath = normalizePath(resolve(config.root, options.dir));
      debug('componentsDirPath', options.componentsDirPath);
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        debug('Loading files...');

        filesPath = await getComponentsPath(options);

        debug('FilesPath: %O', filesPath);

        if (!generatedComponents) generatedComponents = generateComponents(filesPath, options);

        debug('Components: %O', generatedComponents);

        const clientCode = generateClientCode(generatedComponents);

        debug('Client code: %O', clientCode)

        return clientCode;
      }
    },
    async handleHotUpdate({ file, server }) {
      const extensionsRE = new RegExp(`\\.(${options.extensions.join('|')})$`);
      const componentsDir = options.dir;
      const componentsDirPath = options.componentsDirPath;
      // Handle pages HMR
      if (
        (file.startsWith(componentsDirPath) || file.startsWith(componentsDirPath)) &&
        extensionsRE.test(file)
      ) {
        let needReload = false;

        // HMR on new file created
        // Otherwise, handle HMR from custom block
        if (file.includes(componentsDir)) {
          if (
            !filesPath.includes(file.replace(`${componentsDirPath}/`, ''))
          ) {
            generatedComponents = null;
            needReload = true;
          }
        }

        if (needReload) {
          const { moduleGraph } = server;
          const module = moduleGraph.getModuleById(ID);

          debug('Reload for file: %s', file.replace(options.root, ''));

          return [module] as ModuleNode[];
        }
      }
    },
  };
}
Example #14
Source File: config.ts    From vite-ssr with MIT License 5 votes vote down vote up
export function getPluginOptions(viteConfig: ResolvedConfig) {
  return ((
    viteConfig.plugins.find((plugin) => plugin.name === 'vite-ssr') as any
  )?.viteSsrOptions || {}) as ViteSsrPluginOptions
}
Example #15
Source File: index.ts    From vite-plugin-monaco-editor with MIT License 4 votes vote down vote up
export default function monacoEditorPlugin(options: IMonacoEditorOpts = {}): Plugin {
  const languageWorkers =
    options.languageWorkers || (Object.keys(languageWorksByLabel) as EditorLanguageWorks[]);
  const publicPath = options.publicPath || 'monacoeditorwork';
  const globalAPI = options.globalAPI || false;
  const customWorkers = options.customWorkers || [];


  options = {
    languageWorkers,
    publicPath,
    globalAPI,
    customWorkers
  };

  let resolvedConfig: ResolvedConfig;

  return {
    name: 'vite-plugin-moncao-editor',
    configResolved(getResolvedConfig) {
      resolvedConfig = getResolvedConfig;
    },
    configureServer(server) {
      if (isCDN(publicPath)) {
        return;
      }


      workerMiddleware(server.middlewares, resolvedConfig, options);
    },
    transformIndexHtml(html) {
      const works = getWorks(options);
      const workerPaths = getWorkPath(works, options);

      const globals = {
        MonacoEnvironment: `(function (paths) {
          return {
            globalAPI: ${globalAPI},
            getWorkerUrl : function (moduleId, label) {
              var result =  paths[label];
              if (/^((http:)|(https:)|(file:)|(\\/\\/))/.test(result)) {
                var currentUrl = String(window.location);
                var currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length);
                if (result.substring(0, currentOrigin.length) !== currentOrigin) {
                  var js = '/*' + label + '*/importScripts("' + result + '");';
                  var blob = new Blob([js], { type: 'application/javascript' });
                  return URL.createObjectURL(blob);
                }
              }
              return result;
            }
          };
        })(${JSON.stringify(workerPaths, null, 2)})`,
      };

      const descriptor: HtmlTagDescriptor[] = [
        {
          tag: 'script',
          children: Object.keys(globals)
            .map((key) => `self[${JSON.stringify(key)}] = ${globals[key]};`)
            .join('\n'),
          injectTo: 'head-prepend',
        },
      ];
      return descriptor;
    },

    writeBundle() {
      if (isCDN(publicPath)) {
        return;
      }

      const works = getWorks(options);

      const distPath = path.resolve(resolvedConfig.root, resolvedConfig.build.outDir, options.publicPath);

      // write publicPath
      if (!fs.existsSync(distPath)) {
        fs.mkdirSync(
          path.resolve(resolvedConfig.root, resolvedConfig.build.outDir, options.publicPath),
          {
            recursive: true
          }
        );
      }

      for (const work of works) {
        if (!fs.existsSync(cacheDir + getFilenameByEntry(work.entry))) {
          esbuild.buildSync({
            entryPoints: [resolveMonacoPath(work.entry)],
            bundle: true,
            outfile: cacheDir + getFilenameByEntry(work.entry),
          });
        }
        const contentBuffer = fs.readFileSync(cacheDir + getFilenameByEntry(work.entry));
        const destPath = path.resolve(
          resolvedConfig.root,
          resolvedConfig.build.outDir,
          options.publicPath,
          getFilenameByEntry(work.entry)
        );
        fs.writeFileSync(destPath, contentBuffer);
      }
    },
  };
}
Example #16
Source File: index.ts    From vanilla-extract with MIT License 4 votes vote down vote up
export function vanillaExtractPlugin({ identifiers }: Options = {}): Plugin {
  let config: ResolvedConfig;
  let server: ViteDevServer;
  let postCssConfig: PostCSSConfigResult | null;
  const cssMap = new Map<string, string>();

  let virtualExt: string;
  let packageName: string;

  return {
    name: 'vanilla-extract',
    enforce: 'pre',
    configureServer(_server) {
      server = _server;
    },
    config(_userConfig, env) {
      const include =
        env.command === 'serve' ? ['@vanilla-extract/css/injectStyles'] : [];

      return {
        optimizeDeps: { include },
        ssr: {
          external: [
            '@vanilla-extract/css',
            '@vanilla-extract/css/fileScope',
            '@vanilla-extract/css/adapter',
          ],
        },
      };
    },
    async configResolved(resolvedConfig) {
      config = resolvedConfig;
      packageName = getPackageInfo(config.root).name;

      if (config.command === 'serve') {
        postCssConfig = await resolvePostcssConfig(config);
      }

      virtualExt = `.vanilla.${config.command === 'serve' ? 'js' : 'css'}`;
    },
    resolveId(id) {
      if (!id.endsWith(virtualExt)) {
        return;
      }

      const normalizedId = id.startsWith('/') ? id.slice(1) : id;

      if (cssMap.has(normalizedId)) {
        return normalizePath(path.join(config.root, normalizedId));
      }
    },
    load(id) {
      if (!id.endsWith(virtualExt)) {
        return;
      }

      const cssFileId = id.slice(config.root.length + 1);
      const css = cssMap.get(cssFileId);

      if (typeof css !== 'string') {
        return;
      }

      if (!server) {
        return css;
      }

      return outdent`
        import { injectStyles } from '@vanilla-extract/css/injectStyles';
        
        const inject = (css) => injectStyles({
          fileScope: ${JSON.stringify({ filePath: cssFileId })},
          css
        });

        inject(${JSON.stringify(css)});

        import.meta.hot.on('${styleUpdateEvent(cssFileId)}', (css) => {
          inject(css);
        });   
      `;
    },
    async transform(code, id, ssrParam) {
      if (!cssFileFilter.test(id)) {
        return null;
      }

      let ssr: boolean | undefined;

      if (typeof ssrParam === 'boolean') {
        ssr = ssrParam;
      } else {
        ssr = ssrParam?.ssr;
      }

      const index = id.indexOf('?');
      const validId = index === -1 ? id : id.substring(0, index);

      if (ssr) {
        return addFileScope({
          source: code,
          filePath: normalizePath(validId),
          rootPath: config.root,
          packageName,
        });
      }

      const { source, watchFiles } = await compile({
        filePath: validId,
        cwd: config.root,
      });

      for (const file of watchFiles) {
        // In start mode, we need to prevent the file from rewatching itself.
        // If it's a `build --watch`, it needs to watch everything.
        if (config.command === 'build' || file !== id) {
          this.addWatchFile(file);
        }
      }

      const output = await processVanillaFile({
        source,
        filePath: validId,
        identOption:
          identifiers ?? (config.mode === 'production' ? 'short' : 'debug'),
        serializeVirtualCssPath: async ({ fileScope, source }) => {
          const id = `${fileScope.filePath}${virtualExt}`;

          let cssSource = source;

          if (postCssConfig) {
            const postCssResult = await (await import('postcss'))
              .default(postCssConfig.plugins)
              .process(source, {
                ...postCssConfig.options,
                from: undefined,
                map: false,
              });

            cssSource = postCssResult.css;
          }

          if (server && cssMap.has(id) && cssMap.get(id) !== source) {
            const { moduleGraph } = server;
            const moduleId = normalizePath(path.join(config.root, id));
            const module = moduleGraph.getModuleById(moduleId);

            if (module) {
              moduleGraph.invalidateModule(module);
            }

            server.ws.send({
              type: 'custom',
              event: styleUpdateEvent(id),
              data: cssSource,
            });
          }

          cssMap.set(id, cssSource);

          return `import "${id}";`;
        },
      });

      return {
        code: output,
        map: { mappings: '' },
      };
    },
  };
}
Example #17
Source File: index.ts    From convue with MIT License 4 votes vote down vote up
function routePlugin(userOptions: UserOptions = {}): Plugin {
  let config: ResolvedConfig | undefined;
  let filesPath: string[] = [];
  let generatedRoutes: Route[] | null | undefined;
  let middlewareFilesPath: string[] = [];
  let generatedMiddleware: any[] | null | undefined;

  const options: ResolvedOptions = resolveOptions(userOptions);

  return {
    name: 'vite-plugin-pages',
    enforce: 'pre',
    configResolved(_config) {
      config = _config;
      options.root = config.root;
      options.pagesDirPath = normalizePath(resolve(config.root, options.dir));
      options.middlewareDirPath = normalizePath(resolve(config.root, options.middleware));
      debug('pagesDirPath', options.pagesDirPath);
      debug('middlewareDirPath', options.middlewareDirPath);
    },
    resolveId(id) {
      if (id === ID) return ID;
    },
    async load(id) {
      if (id === ID) {
        debug('Loading files...');

        filesPath = await getPagesPath(options);

        debug('FilesPath: %O', filesPath);

        if (!generatedRoutes) generatedRoutes = generateRoutes(filesPath, options);

        debug('Routes: %O', generatedRoutes);

        middlewareFilesPath = await getMiddlesPath(options);

        debug('MiddlewareFilesPath: %O', middlewareFilesPath);

        if (!generatedMiddleware)
          generatedMiddleware = generateMiddleware(middlewareFilesPath, options);

        const clientCode = generateClientCode(generatedRoutes, generatedMiddleware, options);

        // debug('Client code: %O', clientCode)

        return clientCode;
      }
    },
    async handleHotUpdate({ file, server, read }) {
      const extensionsRE = new RegExp(`\\.(${options.extensions.join('|')})$`);
      const pagesDir = options.dir;
      const pagesDirPath = options.pagesDirPath;
      const middlewareDir = options.middleware;
      const middlewareDirPath = options.middlewareDirPath;
      // Handle pages HMR
      if (
        (file.startsWith(pagesDirPath) || file.startsWith(middlewareDirPath)) &&
        extensionsRE.test(file)
      ) {
        let needReload = false;

        // HMR on new file created
        // Otherwise, handle HMR from custom block
        if (file.includes(pagesDir)) {
          if (!filesPath.includes(file.replace(`${pagesDirPath}/`, ''))) {
            generatedRoutes = null;
            needReload = true;
          } else if (generatedRoutes) {
            const content = await read();
            needReload = updateRouteFromHMR(content, file, generatedRoutes, options);
          }
        }

        if (file.includes(middlewareDir)) {
          if (!middlewareFilesPath.includes(file.replace(`${middlewareDirPath}/`, ''))) {
            generatedMiddleware = null;
            needReload = true;
          }
        }

        if (needReload) {
          const { moduleGraph } = server;
          const module = moduleGraph.getModuleById(ID);

          debug('Reload for file: %s', file.replace(options.root, ''));

          return [module] as ModuleNode[];
        }
      }
    },
  };
}
Example #18
Source File: index.ts    From vite-plugin-vue-i18n with MIT License 4 votes vote down vote up
function pluginI18n(
  options: VitePluginVueI18nOptions = { forceStringify: false }
): Plugin {
  debug('plugin options:', options)

  // use `normalizePath` for `options.include`
  let include = options.include
  if (include) {
    if (isArray(include)) {
      include = include.map(item => normalizePath(item))
    } else if (isString(include)) {
      include = normalizePath(include)
    }
  }

  const filter = createFilter(include)
  const runtimeOnly = isBoolean(options.runtimeOnly)
    ? options.runtimeOnly
    : true
  const compositionOnly = isBoolean(options.compositionOnly)
    ? options.compositionOnly
    : true
  const fullIinstall = isBoolean(options.fullInstall)
    ? options.fullInstall
    : true
  const defaultSFCLang = isString(options.defaultSFCLang)
    ? options.defaultSFCLang
    : undefined
  const globalSFCScope = isBoolean(options.globalSFCScope)
    ? options.globalSFCScope
    : false
  let config: ResolvedConfig | null = null

  return {
    name: 'vite-plugin-vue-i18n',

    config(config: UserConfig, { command }) {
      if (command === 'build' && runtimeOnly) {
        normalizeConfigResolveAliias(config)
        if (isArray(config.resolve!.alias)) {
          config.resolve!.alias.push({
            find: 'vue-i18n',
            replacement: 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js'
          })
        } else {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          ;(config.resolve!.alias as any)['vue-i18n'] =
            'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js'
        }
        debug('set vue-i18n runtime only')
      }

      config.define = config.define || {}
      config.define['__VUE_I18N_LEGACY_API__'] = !compositionOnly
      debug(
        `set __VUE_I18N_LEGACY_API__ is '${config.define['__VUE_I18N_LEGACY_API__']}'`
      )

      config.define['__VUE_I18N_FULL_INSTALL__'] = fullIinstall
      debug(
        `set __VUE_I18N_FULL_INSTALL__ is '${config.define['__VUE_I18N_FULL_INSTALL__']}'`
      )

      config.define['__VUE_I18N_PROD_DEVTOOLS__'] = false
    },

    configResolved(_config: ResolvedConfig) {
      // store config
      config = _config

      // json transform handling
      const jsonPlugin = config.plugins.find(p => p.name === 'vite:json')
      if (jsonPlugin) {
        const orgTransform = jsonPlugin.transform // backup @rollup/plugin-json
        jsonPlugin.transform = async function (code: string, id: string) {
          if (!/\.json$/.test(id)) {
            return null
          }
          if (filter(id)) {
            const map = this.getCombinedSourcemap()
            debug('override json plugin', code, map)
            return Promise.resolve({
              code,
              map
            })
          } else {
            debug('org json plugin')
            return orgTransform!.apply(this, [code, id])
          }
        }
      }
    },

    resolveId(id: string) {
      if (id === INTLIFY_BUNDLE_IMPORT_ID) {
        return id
      }
    },

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async load(id: string, ssr: boolean) {
      if (id === INTLIFY_BUNDLE_IMPORT_ID && include) {
        let resourcePaths = [] as string[]
        const includePaths = isArray(include) ? include : [include]
        for (const inc of includePaths) {
          resourcePaths = [...(await fg(inc))]
        }
        // TODO: source-map
        const code = await generateBundleResources(
          resourcePaths,
          config != null ? config.isProduction : false,
          options.forceStringify!
        )
        return Promise.resolve(code)
      }
    },

    async handleHotUpdate({ file, server }) {
      if (/\.(json5?|ya?ml)$/.test(file)) {
        const module = server.moduleGraph.getModuleById(
          INTLIFY_BUNDLE_IMPORT_ID
        )
        if (module) {
          server.moduleGraph.invalidateModule(module)
          return [module!]
        }
      }
    },

    async transform(code: string, id: string) {
      const { filename, query } = parseVueRequest(id)
      debug('transform', id, JSON.stringify(query))

      const parseOptions = getOptions(
        filename,
        config != null ? config.isProduction : false,
        query as Record<string, unknown>,
        options.forceStringify
      ) as CodeGenOptions
      debug('parseOptions', parseOptions)

      let langInfo = 'json'
      if (!query.vue) {
        if (/\.(json5?|ya?ml)$/.test(id) && filter(id)) {
          langInfo = path.parse(filename).ext
          // NOTE:
          // `.json` is handled default in vite, and it's transformed to JS object.
          let _source = code
          if (langInfo === '.json') {
            _source = await getRaw(id)
          }
          const generate = /\.?json5?/.test(langInfo)
            ? generateJSON
            : generateYAML
          const { code: generatedCode } = generate(_source, parseOptions)
          debug('generated code', generatedCode)
          // TODO: error handling & sourcempa
          return Promise.resolve(generatedCode)
        } else {
          return Promise.resolve(code)
        }
      } else {
        // for Vue SFC
        if (isCustomBlock(query as Record<string, unknown>)) {
          if ('src' in query) {
            if (isString(query.lang)) {
              langInfo = query.lang === 'i18n' ? 'json' : query.lang
            } else if (defaultSFCLang) {
              langInfo = defaultSFCLang
            }
          } else {
            if (isString(query.lang)) {
              langInfo = query.lang
            } else if (defaultSFCLang) {
              langInfo = defaultSFCLang
            }
          }
          if (!parseOptions.isGlobal && globalSFCScope) {
            parseOptions.isGlobal = true
          }
          const generate = /\.?json5?/.test(langInfo)
            ? generateJSON
            : generateYAML
          const { code: generatedCode } = generate(code, parseOptions)
          debug('generated code', generatedCode)
          // TODO: error handling & sourcempa
          return Promise.resolve(generatedCode)
        } else {
          return Promise.resolve(code)
        }
      }
    }
  }
}