diff --git a/example/.gitignore b/example/.gitignore index fd7f93b..a52fa38 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -1 +1,2 @@ -/**/django_vite_plugin \ No newline at end of file +/**/django_vite_plugin +/**/.vite \ No newline at end of file diff --git a/example/custom_build/frontend/package.json b/example/custom_build/frontend/package.json index aa16275..99fbe30 100644 --- a/example/custom_build/frontend/package.json +++ b/example/custom_build/frontend/package.json @@ -2,7 +2,7 @@ "name": "django-vite-plugin-custom-build-demo", "private": true, "version": "0.0.0", - "type": "module", + "type": "commonjs", "scripts": { "dev": "vite", "build": "tsc && vite build", @@ -12,5 +12,6 @@ "typescript": "^5.2.2", "vite": "^5.2.0", "django-vite-plugin": "file:../../../vite" - } + }, + "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1" } diff --git a/example/output/jsconfig.json b/example/output/jsconfig.json index f56add4..8ec7b88 100644 --- a/example/output/jsconfig.json +++ b/example/output/jsconfig.json @@ -1,24 +1,24 @@ -{ - "compilerOptions": { - "paths": { - "@/*": [ - "./*" - ], - "@s:home/*": [ - "./home/static/home/*" - ], - "@t:home/*": [ - "./home/templates/home/*" - ], - "@s:another_app/*": [ - "./another_app/static/another_app/*" - ], - "@t:another_app/*": [ - "./another_app/templates/another_app/*" - ] - } - }, - "exclude": [ - "node_modules" - ] +{ + "compilerOptions": { + "paths": { + "@/*": [ + "./*" + ], + "@s:home/*": [ + "./home/static/home/*" + ], + "@t:home/*": [ + "./home/templates/home/*" + ], + "@s:another_app/*": [ + "./another_app/static/another_app/*" + ], + "@t:another_app/*": [ + "./another_app/templates/another_app/*" + ] + } + }, + "exclude": [ + "node_modules" + ] } \ No newline at end of file diff --git a/example/output/package.json b/example/output/package.json index 1df70c6..a7024db 100644 --- a/example/output/package.json +++ b/example/output/package.json @@ -1,23 +1,24 @@ -{ - "private": true, - "version": "0.0.1", - "scripts": { - "dev": "vite", - "build": "vite build" - }, - "type": "module", - "devDependencies": { - "@vitejs/plugin-vue": "^4.5.0", - "autoprefixer": "^10.4.16", - "glob": "^9.3.5", - "postcss": "^8.4.31", - "tailwindcss": "^3.3.5", - "vite": "^5.0.2", - "vite-plugin-inspect": "^0.7.42", - "django-vite-plugin": "file:../../vite" - }, - "dependencies": { - "sweetalert2": "^11.10.1", - "vue": "^3.3.9" - } -} +{ + "private": true, + "version": "0.0.1", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "type": "module", + "devDependencies": { + "@vitejs/plugin-vue": "^4.5.0", + "autoprefixer": "^10.4.16", + "glob": "^9.3.5", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "vite": "^5.0.2", + "vite-plugin-inspect": "^0.7.42", + "django-vite-plugin": "file:../../vite" + }, + "dependencies": { + "sweetalert2": "^11.10.1", + "vue": "^3.3.9" + }, + "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1" +} diff --git a/vite/package.json b/vite/package.json index c3e0758..099d321 100644 --- a/vite/package.json +++ b/vite/package.json @@ -1,6 +1,6 @@ { "name": "django-vite-plugin", - "version": "4.0.2", + "version": "4.0.3", "description": "Django plugin for Vite.", "type": "module", "keywords": [ diff --git a/vite/src/helpers.ts b/vite/src/helpers.ts index 92dd7b1..e494b0f 100644 --- a/vite/src/helpers.ts +++ b/vite/src/helpers.ts @@ -13,6 +13,13 @@ import type { } from './config.js' import { AddressInfo } from 'net' +const BASE_DIR: string = path.dirname( + typeof __dirname === 'undefined' + ? // @ts-ignore + path.dirname(new URL(import.meta.url).pathname) + : __dirname, +) + export function execPythonNoErr( args: string[], config: PluginConfig, @@ -58,7 +65,7 @@ export async function execPythonJSON( export function pluginVersion(): string { try { return JSON.parse( - fs.readFileSync(path.join(__dirname, '../package.json')).toString(), + fs.readFileSync(path.join(BASE_DIR, '/package.json')).toString(), )?.version } catch { return '' diff --git a/vite/src/index.ts b/vite/src/index.ts index d4a6a9e..8a2d751 100644 --- a/vite/src/index.ts +++ b/vite/src/index.ts @@ -1,181 +1,194 @@ -import fs from 'fs' -import { AddressInfo } from 'net' -import path from 'path' -import colors from 'picocolors' -import { Plugin, UserConfig } from 'vite' -import { - pluginVersion, - execPythonJSON, - writeAliases, - getAppAliases, - resolveDevServerUrl, -} from './helpers.js' -import { - DevServerUrl, - InternalConfig, - PluginConfig, - resolveBuildConfig, - resolvePluginConfig, -} from './config.js' - -let DJANGO_VERSION = '...' - -export async function djangoVitePlugin( - config: PluginConfig | string | string[], -): Promise { - if (typeof config === 'string' || Array.isArray(config)) { - config = { input: config } - } - process.stdout.write('Loading configurations...\r') - const appConfig = await execPythonJSON(['--action', 'config'], config) - - if (DJANGO_VERSION === '...') { - process.stdout.write('Loading django version...\r') - execPythonJSON(['--action', 'version'], config).then( - (v: string) => (DJANGO_VERSION = `"${v}"`), - ) - } - - process.stdout.write('\r'.padStart(26, ' ')) - - config = await resolvePluginConfig(config, appConfig) - return [ - djangoPlugin(config as InternalConfig), - fullReload(config as InternalConfig), - ] -} - -let exitHandlersBound =false; - -function djangoPlugin(config: InternalConfig): Plugin { - const defaultAliases: Record = getAppAliases( - config.appConfig, - ) - - if (config.addAliases) { - writeAliases(config, defaultAliases) - } - - let viteDevServerUrl: DevServerUrl; - let userConfigG: UserConfig; - - return { - name: 'django-vite-plugin', - enforce: 'pre', - config: (userConfig: UserConfig, { command }) => { - const build = resolveBuildConfig(config, userConfig.build) - userConfigG = userConfig; - - return { - ...userConfig, - base: - command == 'build' ? config.appConfig.BUILD_URL_PREFIX : '', - root: userConfig.root || config.root || '.', - build, - resolve: { - alias: Array.isArray(userConfig.resolve?.alias) - ? [ - ...(userConfig.resolve?.alias ?? []), - ...Object.keys(defaultAliases).map((alias) => ({ - find: alias, - replacement: defaultAliases[alias], - })), - ] - : { - ...defaultAliases, - ...userConfig.resolve?.alias, - }, - }, - } - }, - configureServer(server) { - server.httpServer?.once('listening', () => { - const address = server.httpServer?.address() - - const isAddressInfo = ( - x: string | AddressInfo | null | undefined, - ): x is AddressInfo => typeof x === 'object' - if (isAddressInfo(address)) { - viteDevServerUrl = resolveDevServerUrl(address, server.config, userConfigG) - fs.writeFileSync(config.appConfig.HOT_FILE, viteDevServerUrl) - setTimeout(() => { - server.config.logger.info( - `\n ${colors.red( - `${colors.bold('DJANGO')}`, - )} ${DJANGO_VERSION} ${colors.dim( - 'plugin', - )} ${colors.bold(`"${pluginVersion()}"`)}`, - ) - server.config.logger.info('') - }, 100) - - if (! exitHandlersBound) { - const clean = () => { - if (fs.existsSync(config.appConfig.HOT_FILE)) { - fs.rmSync(config.appConfig.HOT_FILE) - } - } - - process.on('exit', clean) - process.on('SIGINT', process.exit) - process.on('SIGTERM', process.exit) - process.on('SIGHUP', process.exit) - - exitHandlersBound = true - } - } - }) - - return () => - server.middlewares.use((req, res, next) => { - if (req.url === '/index.html') { - res.statusCode = 404 - res.end( - fs - .readFileSync(path.join(__dirname, 'info.html')) - .toString(), - ) - } - - next() - }) - }, - } -} - -function fullReload(config: InternalConfig): Plugin { - if (!config.reloader) { - return { - name: 'django-vite-plugin-reloader', - } - } - let reloader = config.reloader - if (reloader === true) { - reloader = (file: string) => /\.(html|py)$/.test(file) - } - - return { - name: 'django-vite-plugin-reloader', - configureServer({ ws, watcher }) { - watcher.on('change', (file) => { - // @ts-ignore - if (reloader(file)) { - setTimeout( - () => ws.send({ type: 'full-reload', path: '*' }), - config.delay, - ) - } - }) - if (config.watch) { - config.watch.forEach((file) => { - if (file.indexOf('__pycache__') >= 0) { - return - } - watcher.add(file) - }) - } - }, - } -} - -export default djangoVitePlugin +import fs from 'fs' +import { AddressInfo } from 'net' +import path from 'path' +import colors from 'picocolors' +import { Plugin, UserConfig } from 'vite' +import { + pluginVersion, + execPythonJSON, + writeAliases, + getAppAliases, + resolveDevServerUrl, +} from './helpers.js' +import { + DevServerUrl, + InternalConfig, + PluginConfig, + resolveBuildConfig, + resolvePluginConfig, +} from './config.js' + +let DJANGO_VERSION = '...' + +const THIS_DIR: string = + typeof __dirname === 'undefined' + ? // @ts-ignore + path.dirname(new URL(import.meta.url).pathname) + : __dirname + +export async function djangoVitePlugin( + config: PluginConfig | string | string[], +): Promise { + if (typeof config === 'string' || Array.isArray(config)) { + config = { input: config } + } + process.stdout.write('Loading configurations...\r') + const appConfig = await execPythonJSON(['--action', 'config'], config) + + if (DJANGO_VERSION === '...') { + process.stdout.write('Loading django version...\r') + execPythonJSON(['--action', 'version'], config).then( + (v: string) => (DJANGO_VERSION = `"${v}"`), + ) + } + + process.stdout.write('\r'.padStart(26, ' ')) + + config = await resolvePluginConfig(config, appConfig) + return [ + djangoPlugin(config as InternalConfig), + fullReload(config as InternalConfig), + ] +} + +let exitHandlersBound = false + +function djangoPlugin(config: InternalConfig): Plugin { + const defaultAliases: Record = getAppAliases( + config.appConfig, + ) + + if (config.addAliases) { + writeAliases(config, defaultAliases) + } + + let viteDevServerUrl: DevServerUrl + let userConfigG: UserConfig + + return { + name: 'django-vite-plugin', + enforce: 'pre', + config: (userConfig: UserConfig, { command }) => { + const build = resolveBuildConfig(config, userConfig.build) + userConfigG = userConfig + + return { + ...userConfig, + base: + command == 'build' ? config.appConfig.BUILD_URL_PREFIX : '', + root: userConfig.root || config.root || '.', + build, + resolve: { + alias: Array.isArray(userConfig.resolve?.alias) + ? [ + ...(userConfig.resolve?.alias ?? []), + ...Object.keys(defaultAliases).map((alias) => ({ + find: alias, + replacement: defaultAliases[alias], + })), + ] + : { + ...defaultAliases, + ...userConfig.resolve?.alias, + }, + }, + } + }, + configureServer(server) { + server.httpServer?.once('listening', () => { + const address = server.httpServer?.address() + + const isAddressInfo = ( + x: string | AddressInfo | null | undefined, + ): x is AddressInfo => typeof x === 'object' + if (isAddressInfo(address)) { + viteDevServerUrl = resolveDevServerUrl( + address, + server.config, + userConfigG, + ) + fs.writeFileSync( + config.appConfig.HOT_FILE, + viteDevServerUrl, + ) + setTimeout(() => { + server.config.logger.info( + `\n ${colors.red( + `${colors.bold('DJANGO')}`, + )} ${DJANGO_VERSION} ${colors.dim( + 'plugin', + )} ${colors.bold(`"${pluginVersion()}"`)}`, + ) + server.config.logger.info('') + }, 100) + + if (!exitHandlersBound) { + const clean = () => { + if (fs.existsSync(config.appConfig.HOT_FILE)) { + fs.rmSync(config.appConfig.HOT_FILE) + } + } + + process.on('exit', clean) + process.on('SIGINT', process.exit) + process.on('SIGTERM', process.exit) + process.on('SIGHUP', process.exit) + + exitHandlersBound = true + } + } + }) + + return () => + server.middlewares.use((req, res, next) => { + if (req.url === '/index.html') { + res.statusCode = 404 + res.end( + fs + .readFileSync(path.join(THIS_DIR, 'info.html')) + .toString(), + ) + } + + next() + }) + }, + } +} + +function fullReload(config: InternalConfig): Plugin { + if (!config.reloader) { + return { + name: 'django-vite-plugin-reloader', + } + } + let reloader = config.reloader + if (reloader === true) { + reloader = (file: string) => /\.(html|py)$/.test(file) + } + + return { + name: 'django-vite-plugin-reloader', + configureServer({ ws, watcher }) { + watcher.on('change', (file) => { + // @ts-ignore + if (reloader(file)) { + setTimeout( + () => ws.send({ type: 'full-reload', path: '*' }), + config.delay, + ) + } + }) + if (config.watch) { + config.watch.forEach((file) => { + if (file.indexOf('__pycache__') >= 0) { + return + } + watcher.add(file) + }) + } + }, + } +} + +export default djangoVitePlugin