Skip to content
This repository was archived by the owner on Aug 11, 2022. It is now read-only.

Commit c740d20

Browse files
committed
Provide function to generate webpack configs, initialize Svelte components
1 parent fc7cc6e commit c740d20

File tree

5 files changed

+6606
-15
lines changed

5 files changed

+6606
-15
lines changed

package.json

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,28 @@
22
"name": "svelte_ujs",
33
"version": "0.1.0",
44
"description": "Rails UJS for the svelte-rails gem",
5-
"main": "svelte_ujs/index.js",
6-
"directories": {
7-
"lib": "lib"
8-
},
9-
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
5+
"license": "MIT",
6+
"author": "henning mueller <[email protected]>",
7+
"bugs": {
8+
"url": "https://github.com/nning/svelte-rails/issues"
119
},
10+
"homepage": "https://github.com/nning/svelte-rails#readme",
1211
"repository": {
1312
"type": "git",
1413
"url": "git+https://github.com/nning/svelte-rails.git"
1514
},
16-
"author": "henning mueller <[email protected]>",
17-
"license": "MIT",
18-
"bugs": {
19-
"url": "https://github.com/nning/svelte-rails/issues"
15+
16+
"main": "svelte_ujs/index.js",
17+
"exports": {
18+
"./": "./svelte_ujs/"
19+
},
20+
21+
"devDependencies": {
22+
"@rails/webpacker": "4.2.2",
23+
"webpack-assets-manifest": "^3.1.1",
24+
"before-build-webpack": "^0.2.9"
2025
},
21-
"homepage": "https://github.com/nning/svelte-rails#readme"
26+
"resolutions": {
27+
"webpack-assets-manifest": "https://github.com/pustovalov/webpack-assets-manifest#build"
28+
}
2229
}

svelte_ujs/WaitPlugin.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const config = require('@rails/webpacker/package/config')
2+
const fs = require('fs')
3+
const path = require('path')
4+
const WebpackBeforeBuildPlugin = require('before-build-webpack')
5+
6+
// https://www.viget.com/articles/run-multiple-webpack-configs-sequentially/
7+
class WaitPlugin extends WebpackBeforeBuildPlugin {
8+
constructor(file, interval = 200, timeout = 10000) {
9+
const filePath = path.join(config.outputPath, file)
10+
11+
try {
12+
fs.unlinkSync(filePath)
13+
} catch(e) {
14+
// Ignore if file does not exist
15+
}
16+
17+
super((stats, callback) => {
18+
let start = Date.now()
19+
20+
function poll() {
21+
if (fs.existsSync(filePath)) {
22+
callback()
23+
} else if (Date.now() - start > timeout) {
24+
throw Error(`Waited too long for "${file}" to exist.`)
25+
} else {
26+
setTimeout(poll, interval)
27+
}
28+
}
29+
30+
poll()
31+
})
32+
}
33+
}
34+
35+
module.exports = WaitPlugin

svelte_ujs/getSvelteEnvironments.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const config = require('@rails/webpacker/package/config')
2+
const ConfigList = require('@rails/webpacker/package/config_types/config_list')
3+
const WaitPlugin = require('svelte_ujs/WaitPlugin')
4+
5+
// Use version of WebpackAssetsManifest that supports merging entrypoints in manifest.json
6+
// https://github.com/webdeveric/webpack-assets-manifest/pull/59
7+
const WebpackAssetsManifest = require('webpack-assets-manifest')
8+
9+
const env = process.env.NODE_ENV
10+
const Environment = require('@rails/webpacker/package/environments/' + env)
11+
12+
function getSvelteEnvironments(clientLoader, serverLoader) {
13+
const clientEnvironment = new Environment()
14+
clientEnvironment.entry.delete('server_rendering')
15+
clientEnvironment.loaders.prepend('svelte', clientLoader)
16+
17+
// We need to set merge:true for generating the manifest.json
18+
clientEnvironment.plugins.delete('Manifest')
19+
clientEnvironment.plugins.append(
20+
'Manifest',
21+
new WebpackAssetsManifest({
22+
entrypoints: true,
23+
writeToDisk: true,
24+
publicPath: config.publicPathWithoutCDN,
25+
merge: true
26+
})
27+
)
28+
29+
const serverEnvironment = new Environment()
30+
// TODO Actually delete everything but server_rendering
31+
serverEnvironment.entry.delete('application')
32+
serverEnvironment.loaders.prepend('svelte', serverLoader)
33+
34+
// We need to set merge:true for generating the manifest.json
35+
serverEnvironment.plugins.delete('Manifest')
36+
serverEnvironment.plugins.append(
37+
'Manifest',
38+
new WebpackAssetsManifest({
39+
entrypoints: true,
40+
writeToDisk: true,
41+
publicPath: config.publicPathWithoutCDN,
42+
merge: true
43+
})
44+
)
45+
46+
// Wait for the manifest.json created by clientEnvironment
47+
serverEnvironment.plugins.prepend(
48+
'WaitPlugin',
49+
new WaitPlugin('manifest.json')
50+
)
51+
52+
return [
53+
clientEnvironment,
54+
serverEnvironment
55+
]
56+
}
57+
58+
module.exports = getSvelteEnvironments

svelte_ujs/index.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,41 @@
11
class SvelteRailsUJS {
22
static serverRender(component_name, props) {
3-
const requireComponent = require.context('components', true);
4-
const bundle = requireComponent('./' + component_name).default;
5-
const {html, css} = bundle.render(props);
3+
const requireComponent = require.context('components', true)
4+
const bundle = requireComponent('./' + component_name).default
5+
const {html, css} = bundle.render(props)
66

7-
return `<style>${css.code}</style>` + html;
7+
return `<style>${css.code}</style>` + html
8+
}
9+
10+
static start() {
11+
SvelteRailsUJS.mountComponents()
12+
13+
document.addEventListener('DOMContentLoaded', () => {
14+
SvelteRailsUJS.mountComponents()
15+
})
16+
}
17+
18+
static mountComponents() {
19+
document.querySelectorAll('[data-svelte-class]')
20+
.forEach(SvelteRailsUJS.mountComponent)
21+
}
22+
23+
static mountComponent(target) {
24+
const name = target.dataset.svelteClass
25+
const hydrate = !!target.dataset.hydrate
26+
27+
let props = {}
28+
29+
if (target.dataset.svelteProps) {
30+
props = JSON.parse(target.dataset.svelteProps)
31+
}
32+
33+
const requireComponent = require.context('components', true)
34+
const Component = requireComponent('./' + name).default
35+
36+
console.debug(Component, {target, props, hydrate});
37+
38+
const component = new Component({target, props, hydrate})
839
}
940
}
1041

0 commit comments

Comments
 (0)