@@ -8,24 +8,38 @@ import {
88import * as path from "@std/path" ;
99import * as babel from "@babel/core" ;
1010import { npmWorkaround } from "./patches/npm_workaround.ts" ;
11+ import babelReact from "@babel/preset-react" ;
1112
1213interface DenoState {
1314 type : RequestedModuleType ;
1415}
1516
1617export function deno ( ) : Plugin {
17- let loader : Loader ;
18+ let ssrLoader : Loader ;
19+ let browserLoader : Loader ;
20+
21+ let isDev = false ;
22+
23+ let optimizeDeps : string [ ] | undefined ;
1824
1925 return {
2026 name : "deno" ,
21- async configResolved ( ) {
27+ config ( _ , env ) {
28+ isDev = env . command === "serve" ;
29+ } ,
30+ async configResolved ( cfg ) {
31+ optimizeDeps = cfg . optimizeDeps . include ;
2232 // TODO: Pass conditions
23- loader = await new Workspace ( { } ) . createLoader ( ) ;
33+ ssrLoader = await new Workspace ( { } ) . createLoader ( ) ;
34+ browserLoader = await new Workspace ( { preserveJsx : true } )
35+ . createLoader ( ) ;
2436 } ,
2537 applyToEnvironment ( ) {
2638 return true ;
2739 } ,
2840 async resolveId ( id , importer , options ) {
41+ const loader = options ?. ssr ? ssrLoader : browserLoader ;
42+
2943 // Workaround until upstream PR is merged and released,
3044 // see: https://github.com/vitejs/vite/pull/20558
3145 if ( id . startsWith ( "deno-npm:" ) ) {
@@ -36,6 +50,18 @@ export function deno(): Plugin {
3650 ? parseDenoSpecifier ( importer ) . specifier
3751 : importer ;
3852
53+ if ( optimizeDeps ) {
54+ const match = id . match ( / ^ n p m : ( @ [ ^ / ] + \/ [ ^ / @ ] + | [ ^ / @ ] + ) / ) ;
55+ if ( match !== null ) {
56+ if ( optimizeDeps . includes ( match [ 1 ] ) ) {
57+ return await this . resolve ( match [ 1 ] , importer , options ) ;
58+ }
59+ }
60+ }
61+ if ( id . includes ( "@preact/signals" ) ) {
62+ return this . resolve ( `@preact/signals` , importer , options ) ;
63+ }
64+
3965 try {
4066 // Ensure we're passing a valid importer that Deno understands
4167 const denoImporter = importer && ! importer . startsWith ( "\0" )
@@ -78,7 +104,9 @@ export function deno(): Plugin {
78104 // ignore
79105 }
80106 } ,
81- async load ( id ) {
107+ async load ( id , options ) {
108+ const loader = options ?. ssr ? ssrLoader : browserLoader ;
109+
82110 if ( isDenoSpecifier ( id ) ) {
83111 const { type, specifier } = parseDenoSpecifier ( id ) ;
84112
@@ -110,8 +138,36 @@ export function deno(): Plugin {
110138 return null ;
111139 }
112140
141+ const code = new TextDecoder ( ) . decode ( result . code ) ;
142+
143+ if ( ! options ?. ssr ) {
144+ if ( url . pathname . endsWith ( ".jsx" ) || url . pathname . endsWith ( ".tsx" ) ) {
145+ const result = babel . transform ( code , {
146+ sourceMaps : "inline" ,
147+ filename : id ,
148+ presets : [
149+ [
150+ babelReact ,
151+ {
152+ runtime : "automatic" ,
153+ importSource : "preact" ,
154+ development : isDev ,
155+ } ,
156+ ] ,
157+ ] ,
158+ } ) ;
159+
160+ if ( result !== null && result . code ) {
161+ return {
162+ code : result . code ,
163+ map : result . map ,
164+ } ;
165+ }
166+ }
167+ }
168+
113169 return {
114- code : new TextDecoder ( ) . decode ( result . code ) ,
170+ code,
115171 } ;
116172 } ,
117173 async transform ( _ , id , options ) {
@@ -130,12 +186,15 @@ export function deno(): Plugin {
130186 actualId = path . toFileUrl ( actualId ) . href ;
131187 }
132188
133- const resolved = await loader . resolve (
189+ const resolved = await ssrLoader . resolve (
134190 actualId ,
135191 undefined ,
136192 ResolutionMode . Import ,
137193 ) ;
138- const result = await loader . load ( resolved , RequestedModuleType . Default ) ;
194+ const result = await ssrLoader . load (
195+ resolved ,
196+ RequestedModuleType . Default ,
197+ ) ;
139198 if ( result . kind === "external" ) {
140199 return ;
141200 }
0 commit comments