1
- const { basename, extname, posix , relative } = require ( 'path' ) ;
1
+ const { basename, extname, relative } = require ( 'path' ) ;
2
2
const { compile, preprocess } = require ( 'svelte' ) ;
3
3
const { getOptions } = require ( 'loader-utils' ) ;
4
- const { statSync, utimesSync, writeFileSync } = require ( 'fs' ) ;
5
- const { tmpdir } = require ( 'os' ) ;
4
+ const VirtualModules = require ( './lib/virtual' ) ;
6
5
7
6
const hotApi = require . resolve ( './lib/hot-api.js' ) ;
8
7
9
8
function makeHot ( id , code , hotOptions ) {
10
9
const options = JSON . stringify ( hotOptions ) ;
11
10
const replacement = `
12
-
13
11
if (module.hot) {
14
-
15
12
const { configure, register, reload } = require('${ posixify ( hotApi ) } ');
16
13
17
14
module.hot.accept();
@@ -26,7 +23,6 @@ if (module.hot) {
26
23
}
27
24
}
28
25
29
-
30
26
export default $2;
31
27
` ;
32
28
@@ -80,7 +76,15 @@ function deprecatePreprocessOptions(options) {
80
76
options . preprocess = options . preprocess || preprocessOptions ;
81
77
}
82
78
79
+ const virtualModuleInstances = new Map ( ) ;
80
+
83
81
module . exports = function ( source , map ) {
82
+ if ( this . _compiler && ! virtualModuleInstances . has ( this . _compiler ) ) {
83
+ virtualModuleInstances . set ( this . _compiler , new VirtualModules ( this . _compiler ) ) ;
84
+ }
85
+
86
+ const virtualModules = virtualModuleInstances . get ( this . _compiler ) ;
87
+
84
88
this . cacheable ( ) ;
85
89
86
90
const options = Object . assign ( { } , this . options , getOptions ( this ) ) ;
@@ -90,47 +94,41 @@ module.exports = function(source, map) {
90
94
const isProduction = this . minimize || process . env . NODE_ENV === 'production' ;
91
95
92
96
options . filename = this . resourcePath ;
93
- if ( ! options . format ) {
94
- options . format = this . version === 1 ? options . format || 'cjs' : 'es' ;
95
- }
96
- if ( ! options . shared ) {
97
- options . shared = options . format === 'es' && 'svelte/shared.js' ;
98
- }
99
-
97
+ if ( ! ( 'format' in options ) ) options . format = 'es' ;
98
+ if ( ! ( 'shared' in options ) ) options . shared = options . format === 'es' && 'svelte/shared.js' ;
99
+ if ( ! ( 'name' in options ) ) options . name = capitalize ( sanitize ( options . filename ) ) ;
100
+ if ( ! ( 'onwarn' in options ) ) options . onwarn = warning => this . emitWarning ( new Error ( warning ) ) ;
100
101
if ( options . emitCss ) options . css = false ;
101
102
102
- if ( ! options . name ) options . name = capitalize ( sanitize ( options . filename ) ) ;
103
-
104
- if ( ! options . onwarn ) options . onwarn = warning => this . emitWarning ( new Error ( warning ) ) ;
105
-
106
103
deprecatePreprocessOptions ( options ) ;
107
104
options . preprocess . filename = options . filename ;
108
105
109
106
preprocess ( source , options . preprocess ) . then ( processed => {
110
- let { js, css, ast } = normalize ( compile ( processed . toString ( ) , options ) ) ;
111
-
112
- if ( options . emitCss && css . code ) {
113
- const posixTmpdir = posixify ( tmpdir ( ) ) ;
114
- const tmpFile = posix . join ( posixTmpdir , 'svelte-' + ast . hash + '.css' ) ;
115
-
116
- css . code += '\n/*# sourceMappingURL=' + css . map . toUrl ( ) + '*/' ;
117
- js . code = js . code + `\nrequire('${ tmpFile } ');\n` ;
118
-
119
- writeFileSync ( tmpFile , css . code ) ;
120
- const { atime, mtime } = statSync ( tmpFile ) ;
121
- utimesSync ( tmpFile , new Date ( atime . getTime ( ) - 99999 ) , new Date ( mtime . getTime ( ) - 99999 ) ) ;
122
- }
107
+ let { js, css } = normalize ( compile ( processed . toString ( ) , options ) ) ;
123
108
124
109
if ( options . hotReload && ! isProduction && ! isServer ) {
125
110
const hotOptions = Object . assign ( { } , options . hotOptions ) ;
126
111
const id = JSON . stringify ( relative ( process . cwd ( ) , options . filename ) ) ;
127
112
js . code = makeHot ( id , js . code , hotOptions ) ;
128
113
}
129
114
115
+ if ( options . emitCss && css . code ) {
116
+ const cssFilepath = options . filename . replace (
117
+ / \. [ ^ / . ] + $ / ,
118
+ `.svelte.css`
119
+ ) ;
120
+ css . code += '\n/*# sourceMappingURL=' + css . map . toUrl ( ) + '*/' ;
121
+ js . code = js . code + `\nimport '${ cssFilepath } ';\n` ;
122
+
123
+ if ( virtualModules ) {
124
+ virtualModules . writeModule ( cssFilepath , css . code ) ;
125
+ }
126
+ }
127
+
130
128
callback ( null , js . code , js . map ) ;
131
129
} , err => callback ( err ) ) . catch ( err => {
132
130
// wrap error to provide correct
133
131
// context when logging to console
134
132
callback ( new Error ( `${ err . name } : ${ err . toString ( ) } ` ) ) ;
135
133
} ) ;
136
- } ;
134
+ } ;
0 commit comments