12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { readFile } from 'fs/promises';
- import { basename, dirname } from 'path';
- import { LibraryFormats, Plugin, ResolvedConfig } from 'vite';
- export interface UserScriptOptions {
- entry: string;
- format: LibraryFormats;
- name?: string;
- port?: number;
- cdn?: string;
- }
- export function _userscript(options: UserScriptOptions): Plugin {
- let config: ResolvedConfig;
- return {
- name: 'userscript',
- config() {
- const name = options.name ?? basename(dirname(options.entry));
- return {
- build: {
- lib: {
- name: name,
- formats: [ options.format ],
- entry: {
- [name]: options.entry
- }
- },
- rollupOptions: {
- output: {
- entryFileNames: '[name].user.js'
- }
- }
- }
- };
- },
- configResolved(resolvedConfig) {
- config = resolvedConfig;
- },
- async generateBundle(outputOptions, bundle) {
- for (const chunk of Object.values(bundle)) {
- if (chunk.type !== 'chunk') continue;
- if (!chunk.isEntry) continue;
- if (!chunk.facadeModuleId) continue;
- const code = await readFile(chunk.facadeModuleId, { encoding: 'utf8' });
- let header = '';
- for (const line of code.split('\n')) {
- if (!line.startsWith('//')) break;
- header += line + '\n';
- }
- let url = '';
- if (config.mode === 'production') {
- if (options.cdn) url = `${options.cdn}${chunk.name}.user.js`;
- } else {
- if (options.port) url = `http://localhost:${options.port}/${chunk.name}.user.js`;
- }
- if (url) {
- header = header.replaceAll(
- '// ==/UserScript==',
- `// @downloadURL ${url}\n` +
- `// @updateURL ${url}\n` +
- '// ==/UserScript=='
- );
- }
- chunk.code = header + '\n' + chunk.code;
- }
- }
- };
- }
|