@@ -4,6 +4,7 @@ const { babel } = require('@rollup/plugin-babel')
4
4
const { nodeResolve } = require ( '@rollup/plugin-node-resolve' )
5
5
const commonjs = require ( '@rollup/plugin-commonjs' )
6
6
const json = require ( '@rollup/plugin-json' )
7
+ const css = require ( 'rollup-plugin-css-only' )
7
8
const replace = require ( '@rollup/plugin-replace' )
8
9
const livereload = require ( 'rollup-plugin-livereload' )
9
10
const terser = require ( 'rollup-plugin-terser' ) . terser
@@ -19,99 +20,115 @@ const buildPath = 'dist'
19
20
const entryPoint = `${ appPath } /src/index.svelte`
20
21
const entryPointRegexp = / i n d e x \. s v e l t e $ /
21
22
const moduleName = packageJson . name
23
+ // Replace special characters for allowing scoped packages like "@scope/package"
24
+ const displayModuleName = moduleName . replace ( '@' , '' ) . replace ( '/' , '-' )
22
25
const moduleVersion = packageJson . version
23
26
27
+ // Used for package.json "main" property
28
+ const moduleFile = `${ buildPath } /${ displayModuleName } .js`
29
+
30
+ const bundleName = `${ displayModuleName } .${ moduleVersion } .js`
31
+
24
32
const outputOptions = {
25
33
sourcemap : true ,
26
34
format : 'iife' ,
27
35
name : 'App' ,
28
- file : `${ buildPath } /${ moduleName } . ${ moduleVersion } .js ` ,
36
+ file : `${ buildPath } /${ bundleName } ` ,
29
37
}
30
38
31
- const commonRollupPlugins = [
32
- json ( ) ,
33
-
34
- // If you have external dependencies installed from
35
- // npm, you'll most likely need these plugins. In
36
- // some cases you'll need additional configuration -
37
- // consult the documentation for details:
38
- // https://github.com/rollup/plugins/tree/master/packages/commonjs
39
- nodeResolve ( {
40
- browser : true ,
41
- dedupe : [ 'svelte' ] ,
42
- } ) ,
43
-
44
- commonjs ( ) ,
45
-
46
- // transpile to ES2015+
47
- babel ( {
48
- extensions : [ '.js' , '.mjs' , '.html' , '.svelte' ] ,
49
- babelHelpers : 'runtime' ,
50
- } ) ,
51
- ]
52
-
53
- async function generateNestedCSS ( ) {
54
- let cssChunk
55
-
39
+ async function buildWebComponent ( { minify } ) {
56
40
// 1. Create a bundle
57
41
const bundle = await rollup . rollup ( {
58
42
input : entryPoint ,
59
43
plugins : [
60
44
svelte ( {
61
- // all nested child elements are built as normal svelte components
62
- customElement : false ,
45
+ compilerOptions : {
46
+ dev : false ,
47
+
48
+ // all nested child elements are built as normal svelte components
49
+ customElement : false ,
50
+ } ,
51
+ emitCss : true ,
63
52
exclude : entryPointRegexp ,
64
53
preprocess : sveltePreprocess ( ) ,
65
- // Extract CSS into a variable
66
- css : css => ( cssChunk = css . code ) ,
67
54
} ) ,
68
55
svelte ( {
69
- customElement : true ,
56
+ compilerOptions : {
57
+ // enable run-time checks when not in production
58
+ dev : ! production ,
59
+
60
+ // we're generating a -- Web Component -- from index.svelte
61
+ customElement : true ,
62
+ } ,
63
+ emitCss : false ,
70
64
include : entryPointRegexp ,
71
65
preprocess : sveltePreprocess ( ) ,
72
66
} ) ,
73
67
74
- ...commonRollupPlugins ,
75
- ] ,
76
- } )
77
-
78
- // 2. Generate output specific code in-memory
79
- // You can call this function multiple times on the same bundle object
80
- await bundle . generate ( outputOptions )
68
+ // HACK! Inject nested CSS into custom element shadow root
69
+ css ( {
70
+ output ( nestedCSS , styleNodes , bundle ) {
71
+ const code = bundle [ bundleName ] . code
72
+ const escapedCssChunk = nestedCSS
73
+ . replace ( / \n / g, '' )
74
+ . replace ( / [ \\ " ' ] / g, '\\$&' )
75
+ . replace ( / \u0000 / g, '\\0' )
76
+
77
+ const matches = code . match (
78
+ minify
79
+ ? / .s h a d o w R o o t .i n n e r H T M L = ' < s t y l e > ( .* ) < \/ s t y l e > ' /
80
+ : / .s h a d o w R o o t .i n n e r H T M L = " < s t y l e > ( .* ) < \/ s t y l e > " / ,
81
+ )
82
+
83
+ if ( matches && matches [ 1 ] ) {
84
+ const style = matches [ 1 ]
85
+ bundle [ bundleName ] . code = code . replace (
86
+ style ,
87
+ `${ style } ${ escapedCssChunk } ` ,
88
+ )
89
+ } else {
90
+ throw new Error (
91
+ "Couldn't shadowRoot <style> tag for injecting styles" ,
92
+ )
93
+ }
94
+ } ,
95
+ } ) ,
81
96
82
- // 3. Escape css chunk characters.
83
- // For embedding the chunk into the main custom element
84
- const escapedCssChunk = cssChunk
85
- . replace ( / \n / g, '' )
86
- . replace ( / [ \\ " ' ] / g, '\\$&' )
87
- . replace ( / \u0000 / g, '\\0' )
97
+ // HACK! Fix svelte/transitions in web components
88
98
89
- return escapedCssChunk
90
- }
99
+ // Use shadow root instead of document for transition style injecting
100
+ replace ( {
101
+ '.ownerDocument' : '.getRootNode()' ,
102
+ delimiters : [ '' , '' ] ,
103
+ } ) ,
91
104
92
- async function buildWebComponent ( { nestedCSS, minify } ) {
93
- // 1. Create a bundle
94
- const bundle = await rollup . rollup ( {
95
- input : entryPoint ,
96
- plugins : [
97
- replace ( { 'module-name' : moduleName } ) ,
98
- svelte ( {
99
- dev : false ,
100
- // all nested child elements are built as normal svelte components
101
- customElement : false ,
102
- exclude : entryPointRegexp ,
103
- preprocess : sveltePreprocess ( ) ,
105
+ // Append styles to shadow root
106
+ replace ( {
107
+ '.head.appendChild' : '.appendChild' ,
108
+ delimiters : [ '' , '' ] ,
104
109
} ) ,
105
- svelte ( {
106
- // enable run-time checks when not in production
107
- dev : ! production ,
108
- // we're generating a -- Web Component -- from index.svelte
109
- customElement : true ,
110
- include : entryPointRegexp ,
111
- preprocess : sveltePreprocess ( ) ,
110
+
111
+ // END HACK
112
+
113
+ json ( ) ,
114
+
115
+ // If you have external dependencies installed from
116
+ // npm, you'll most likely need these plugins. In
117
+ // some cases you'll need additional configuration -
118
+ // consult the documentation for details:
119
+ // https://github.com/rollup/plugins/tree/master/packages/commonjs
120
+ nodeResolve ( {
121
+ browser : true ,
122
+ dedupe : [ 'svelte' ] ,
112
123
} ) ,
113
124
114
- ...commonRollupPlugins ,
125
+ commonjs ( ) ,
126
+
127
+ // transpile to ES2015+
128
+ babel ( {
129
+ extensions : [ '.js' , '.mjs' , '.html' , '.svelte' ] ,
130
+ babelHelpers : 'runtime' ,
131
+ } ) ,
115
132
116
133
// Watch the `public` directory and refresh the
117
134
// browser on changes when not in production
@@ -128,39 +145,20 @@ async function buildWebComponent({ nestedCSS, minify }) {
128
145
const { output } = await bundle . generate ( outputOptions )
129
146
const { code, map } = output [ 0 ]
130
147
131
- // 3. Inject CSS chunk into custom element shadow root
132
- const matches = code . match (
133
- minify
134
- ? / .s h a d o w R o o t .i n n e r H T M L = ' < s t y l e > ( .* ) < \/ s t y l e > ' /
135
- : / _ t h i s .s h a d o w R o o t .i n n e r H T M L = \" < s t y l e > ( .* ) < \/ s t y l e > \" / ,
136
- )
137
-
138
- let updatedCode = code
139
-
140
- if ( matches && matches [ 1 ] ) {
141
- const style = matches [ 1 ]
142
- updatedCode = code . replace ( style , `${ style } ${ nestedCSS } ` )
143
- }
144
-
145
- // 4. HACK! Fix svelte/transitions in web components
146
- updatedCode = updatedCode
147
- // Use shadow root instead of document for transition style injecting
148
- . replace ( / \. o w n e r D o c u m e n t / , '.getRootNode()' )
149
- // Append styles to shadow root
150
- . replace ( / \. h e a d \. a p p e n d C h i l d / , '.appendChild' )
151
-
152
- // 5. Write bundles into files
148
+ // 3. Write bundles into files
153
149
const fileName = minify
154
150
? `${ outputOptions . file . replace ( '.js' , '.min.js' ) } `
155
151
: outputOptions . file
156
152
157
- fs . writeFile ( fileName , updatedCode , err => {
153
+ // Normal bundle
154
+ fs . writeFile ( fileName , code , err => {
158
155
if ( err ) {
159
156
console . error ( err )
160
157
process . exit ( 1 )
161
158
}
162
159
} )
163
160
161
+ // Only create .map.js when code is minified
164
162
if ( minify ) {
165
163
fs . writeFile ( fileName . replace ( '.js' , '.js.map' ) , map . toString ( ) , err => {
166
164
if ( err ) {
@@ -169,19 +167,27 @@ async function buildWebComponent({ nestedCSS, minify }) {
169
167
}
170
168
} )
171
169
}
170
+
171
+ // Generic bundle for using as module entry point
172
+ if ( ! minify ) {
173
+ fs . writeFile ( moduleFile , code , err => {
174
+ if ( err ) {
175
+ console . error ( err )
176
+ process . exit ( 1 )
177
+ }
178
+ } )
179
+ }
172
180
}
173
181
174
182
async function main ( ) {
175
183
try {
176
184
shell . mkdir ( '-p' , buildPath )
177
185
178
- const nestedCSS = await generateNestedCSS ( )
179
-
180
186
// builds readable bundle of the web component
181
- await buildWebComponent ( { nestedCSS , minify : false } )
187
+ await buildWebComponent ( { minify : false } )
182
188
183
189
// builds minified bundle with sourcemap
184
- await buildWebComponent ( { nestedCSS , minify : true } )
190
+ await buildWebComponent ( { minify : true } )
185
191
} catch ( ex ) {
186
192
console . error ( ex )
187
193
process . exit ( 1 )
0 commit comments