jass-vue-sfc 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +101 -0
- data/lib/jass/vue/sfc/compiler.rb +88 -0
- data/lib/jass/vue/sfc/processor.rb +25 -0
- data/lib/jass/vue/sfc/version.rb +7 -0
- data/lib/jass/vue/sfc.rb +16 -0
- data/lib/jass-vue-sfc.rb +1 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ab40368ebb1bc5a2c21ea1ac7bde01c96a63897f2b072440849d047e510c8494
|
4
|
+
data.tar.gz: d82d4dd740cc97e33226bb644dcbae8a6525cd545c1e6ff6eb5b4306601550b0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '081894ef43d71ddf65e050436020fa61657043de187907debe17952fe54397c8977bdae706511e4081980a370afed63e9036b95bbf7f007cfd23bc453e29cb8e'
|
7
|
+
data.tar.gz: 01acb42ca64cc5ce55cad25cbda8cc2b34394138024bc9bd7031c8b97a562cf7887fd30fbedefb24b4dd48f5e762773a71a67210dc43f86f158f614ef5769f28
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2021 Matthias Grosser
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/jass-vue-sfc.svg)](http://badge.fury.io/rb/jass-vue-sfc)
|
2
|
+
[![build](https://github.com/mtgrosser/jass-vue-sfc/actions/workflows/build.yml/badge.svg)](https://github.com/mtgrosser/jass-vue-sfc/actions/workflows/build.yml)
|
3
|
+
|
4
|
+
# Jass::Vue::SFC – Vue SFC support for the Rails asset pipeline
|
5
|
+
|
6
|
+
`Jass::Vue::SFC` provides [Vue Single File Component](https://v3.vuejs.org/guide/single-file-component.html) support for Sprockets and the Rails asset pipeline.
|
7
|
+
|
8
|
+
Vue SFCs will be compiled to ES modules, which can be imported using the new Rails [Import Maps](https://github.com/rails/importmap-rails) or regular `<script module>` tags.
|
9
|
+
|
10
|
+
## Why?
|
11
|
+
|
12
|
+
Modern browsers support native loading of ES modules using the `import` statement.
|
13
|
+
By leveraging the new Rails Import Maps, modular JS applications can be built
|
14
|
+
without having to integrate a complex and tedious JS build pipeline.
|
15
|
+
|
16
|
+
However, framework-specific component formats like the Vue SFC format could not be used this
|
17
|
+
way till now.
|
18
|
+
|
19
|
+
`Jass::Vue::SFC` enables the asset pipeline to compile `.vue` files to ES modules,
|
20
|
+
allowing to build modular Vue applications in a clear and straightforward way,
|
21
|
+
without the necessity of external build tools.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
### Gemfile
|
26
|
+
```ruby
|
27
|
+
gem 'jass-vue-sfc'
|
28
|
+
```
|
29
|
+
|
30
|
+
### JS dependencies
|
31
|
+
Add `@vue/compiler-sfc` to your JS dependencies:
|
32
|
+
```sh
|
33
|
+
$ yarn add @vue/compiler-sfc
|
34
|
+
```
|
35
|
+
|
36
|
+
### Node.js
|
37
|
+
|
38
|
+
`Jass::Vue::SFC` depends on [Nodo](https://github.com/mtgrosser/nodo), which requires a working Node.js installation.
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
Place your `.vue` components inside your regular asset path, e.g. under `app/assets/javascripts` or `app/javascript`.
|
43
|
+
|
44
|
+
In `app/javascript/components/HelloWorld.vue`:
|
45
|
+
|
46
|
+
```vue
|
47
|
+
<script>
|
48
|
+
export default {
|
49
|
+
data() {
|
50
|
+
return {
|
51
|
+
greeting: 'Hello World!'
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
</script>
|
56
|
+
|
57
|
+
<template>
|
58
|
+
<p class="greeting">{{ greeting }}</p>
|
59
|
+
</template>
|
60
|
+
```
|
61
|
+
|
62
|
+
Then add the component to `app/assets/config/manifest.js`:
|
63
|
+
|
64
|
+
```js
|
65
|
+
//= link app/javascript/components/HelloWorld.js
|
66
|
+
```
|
67
|
+
|
68
|
+
Make sure to link the file as `.js` instead of `.vue`. Sprockets will take care of
|
69
|
+
converting it into an ES module.
|
70
|
+
|
71
|
+
In your HTML code, load the component as a module:
|
72
|
+
|
73
|
+
```erb
|
74
|
+
<%= javascript_include_tag 'HelloWorld.js', module: true %>
|
75
|
+
```
|
76
|
+
|
77
|
+
### Components with imports
|
78
|
+
|
79
|
+
If you want to use module `import`s within your components, pin them in your Rails importmap:
|
80
|
+
|
81
|
+
```
|
82
|
+
# config/importmap.rb
|
83
|
+
pin 'vue'
|
84
|
+
pin 'HelloWorld.vue', to: 'HelloWorld.js'
|
85
|
+
```
|
86
|
+
|
87
|
+
Then just use them in your component:
|
88
|
+
|
89
|
+
```vue
|
90
|
+
<script>
|
91
|
+
import Vue from 'vue';
|
92
|
+
...
|
93
|
+
</script>
|
94
|
+
```
|
95
|
+
|
96
|
+
## Limitations
|
97
|
+
|
98
|
+
Currently, the following things are not (yet) supported:
|
99
|
+
|
100
|
+
- extracting the `<style>` section of the SFC
|
101
|
+
- source maps
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
class Jass::Vue::SFC::Compiler < Nodo::Core
|
4
|
+
const :COMP_IDENTIFIER, '__sfc__'
|
5
|
+
|
6
|
+
require compiler: '@vue/compiler-sfc'
|
7
|
+
|
8
|
+
class_function def compile(source, filename)
|
9
|
+
filename = File.basename(filename)
|
10
|
+
id = Digest::MD5.hexdigest(filename)[0..7]
|
11
|
+
compile_component(source, filename, id)
|
12
|
+
end
|
13
|
+
|
14
|
+
function :compile_component, <<~'JS'
|
15
|
+
(source, filename, id) => {
|
16
|
+
let code = '';
|
17
|
+
nodo.debug(`Compiling component ${filename}`);
|
18
|
+
const { errors, descriptor } = compiler.parse(source, { filename, sourceMap: true });
|
19
|
+
|
20
|
+
const [clientScript, bindings] = compile_script(descriptor, id);
|
21
|
+
if (clientScript) {
|
22
|
+
code += clientScript;
|
23
|
+
}
|
24
|
+
const clientTemplate = compile_template(descriptor, id, bindings);
|
25
|
+
if (clientTemplate) {
|
26
|
+
code += clientTemplate;
|
27
|
+
}
|
28
|
+
|
29
|
+
return code;
|
30
|
+
}
|
31
|
+
JS
|
32
|
+
|
33
|
+
function :compile_script, <<~'JS'
|
34
|
+
(descriptor, id) => {
|
35
|
+
if (descriptor.script || descriptor.scriptSetup) {
|
36
|
+
try {
|
37
|
+
const compiledScript = compiler.compileScript(descriptor, {
|
38
|
+
id,
|
39
|
+
refSugar: true,
|
40
|
+
inlineTemplate: true,
|
41
|
+
templateOptions: { ssrCssVars: descriptor.cssVars }
|
42
|
+
});
|
43
|
+
let code = '';
|
44
|
+
if (compiledScript.bindings) {
|
45
|
+
code += `\n/* Analyzed bindings: ${JSON.stringify(compiledScript.bindings, null, 2)} */`;
|
46
|
+
}
|
47
|
+
code += `\n` + compiler.rewriteDefault(compiledScript.content, COMP_IDENTIFIER);
|
48
|
+
return [code, compiledScript.bindings];
|
49
|
+
} catch (e) {
|
50
|
+
e.fileName = descriptor.filename;
|
51
|
+
throw e;
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
return [`\nconst ${COMP_IDENTIFIER} = {}`, undefined];
|
55
|
+
}
|
56
|
+
}
|
57
|
+
JS
|
58
|
+
|
59
|
+
function :compile_template, <<~'JS'
|
60
|
+
(descriptor, id, bindingMetadata) => {
|
61
|
+
if (descriptor.template && !descriptor.scriptSetup) {
|
62
|
+
const templateResult = compiler.compileTemplate({
|
63
|
+
source: descriptor.template.content,
|
64
|
+
filename: descriptor.filename,
|
65
|
+
id: id,
|
66
|
+
scoped: descriptor.styles.some(s => s.scoped),
|
67
|
+
slotted: descriptor.slotted,
|
68
|
+
ssr: false,
|
69
|
+
ssrCssVars: descriptor.cssVars,
|
70
|
+
isProd: 'production' == process.env.NODE_ENV,
|
71
|
+
compilerOptions: { bindingMetadata }
|
72
|
+
});
|
73
|
+
if (templateResult.errors.length) {
|
74
|
+
const error = templateResult.errors[0];
|
75
|
+
error.fileName = descriptor.filename;
|
76
|
+
throw error;
|
77
|
+
}
|
78
|
+
let code = `${templateResult.code.replace(/\nexport (function|const) (render|ssrRender)/, '$1 render')}\n`;
|
79
|
+
code += `${COMP_IDENTIFIER}.__file = ${JSON.stringify(descriptor.filename)}\n`;
|
80
|
+
code += `${COMP_IDENTIFIER}.render = render\n`;
|
81
|
+
code += `export default ${COMP_IDENTIFIER}\n`;
|
82
|
+
|
83
|
+
return code;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
JS
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Jass::Vue::SFC::Processor
|
2
|
+
VERSION = '1'
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def cache_key
|
7
|
+
@cache_key ||= "#{name}:#{VERSION}".freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(input)
|
11
|
+
data = input[:data]
|
12
|
+
|
13
|
+
js, map = input[:cache].fetch([self.cache_key, data]) do
|
14
|
+
result = Jass::Vue::SFC::Compiler.compile(data, input[:filename])
|
15
|
+
[result, nil]
|
16
|
+
end
|
17
|
+
|
18
|
+
#map = SourceMapUtils.format_source_map(map, input)
|
19
|
+
#map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map)
|
20
|
+
|
21
|
+
{ data: js } #, map: map }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/jass/vue/sfc.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nodo'
|
2
|
+
|
3
|
+
require_relative 'sfc/version'
|
4
|
+
require_relative 'sfc/compiler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'sprockets'
|
8
|
+
rescue LoadError
|
9
|
+
# Sprockets not available
|
10
|
+
end
|
11
|
+
|
12
|
+
if defined?(Sprockets)
|
13
|
+
require_relative 'sfc/processor'
|
14
|
+
Sprockets.register_mime_type 'text/vue-sfc', extensions: %w[.vue], charset: :unicode
|
15
|
+
Sprockets.register_transformer 'text/vue-sfc', 'application/javascript', Jass::Vue::SFC::Processor
|
16
|
+
end
|
data/lib/jass-vue-sfc.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'jass/vue/sfc'
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jass-vue-sfc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthias Grosser
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-10-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nodo
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.6
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- mtgrosser@gmx.net
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- lib/jass-vue-sfc.rb
|
93
|
+
- lib/jass/vue/sfc.rb
|
94
|
+
- lib/jass/vue/sfc/compiler.rb
|
95
|
+
- lib/jass/vue/sfc/processor.rb
|
96
|
+
- lib/jass/vue/sfc/version.rb
|
97
|
+
homepage: https://github.com/mtgrosser/jass-vue-sfc
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.3.0
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubygems_version: 3.0.3
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: Compile Vue SFCs for Sprockets
|
120
|
+
test_files: []
|