webpacker-svelte 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Renaud Chaput
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.
@@ -0,0 +1,195 @@
1
+ # Webpacker-Svelte [![CircleCI](https://circleci.com/gh/will-wow/webpacker-svelte.svg?style=svg)](https://circleci.com/gh/will-wow/webpacker-svelte)
2
+
3
+ _**Note:** This is the documentation for the Git master branch. Documentation for the latest release (0.0.0) is [available here](https://github.com/will-wow/webpacker-svelte/tree/v0.0.0)._
4
+
5
+ Webpacker-Svelte makes it easy to use [Svelte](https://svelte.dev) with [Webpacker](https://github.com/rails/webpacker) in your Rails applications.
6
+
7
+ This is a port of [@renchap](https://github.com/renchap)'s excellent [webpacker-react](https://github.com/renchap/webpacker-react).
8
+
9
+ It supports Webpacker 1.2+.
10
+
11
+ An example application is available: https://github.com/will-wow/svelte-on-rails/
12
+
13
+ ## Installation
14
+
15
+ Your Rails application needs to use Webpacker and have the Svelte integration done. Please refer to their documentation documentation for this: https://github.com/rails/webpacker/blob/master/README.md#svelte
16
+
17
+ First, you need to add the webpacker-svelte gem to your Rails app Gemfile:
18
+
19
+ ```ruby
20
+ gem 'webpacker-svelte', "~> 0.0.0"
21
+ ```
22
+
23
+ Once done, run `bundle` to install the gem.
24
+
25
+ Then you need to update your `package.json` file to include the `webpacker-svelte` NPM module:
26
+
27
+ `./bin/yarn add webpacker-svelte`
28
+
29
+ You are now all set!
30
+
31
+ ### Note about versions
32
+
33
+ Webpacker-Svelte contains two parts: a Javascript module and a Ruby gem. Both of those components respect [semantic versioning](http://semver.org). **When upgrading the gem, you need to upgrade the NPM module to the same minor version**. New patch versions can be released for each of the two independently, so it is ok to have the NPM module at version `A.X.Y` and the gem at version `A.X.Z`, but you should never have a different `A` or `X`.
34
+
35
+ ## Usage
36
+
37
+ The first step is to register your root components (those you want to load from your HTML).
38
+ In your pack file (`app/javascript/packs/*.js`), import your components as well as `webpacker-svelte` and register them. Considering you have a component in `app/javascript/components/hello.js`:
39
+
40
+ ```javascript
41
+ import Hello from "components/hello.svelte";
42
+ import WebpackerSvelte from "webpacker-svelte";
43
+
44
+ WebpackerSvelte.setup({ Hello }); // ES6 shorthand for {Hello: Hello}
45
+ ```
46
+
47
+ ### With Turbolinks
48
+
49
+ You have to make sure Turbolinks is loaded before calling `WebpackerSvelte.initialize()`.
50
+
51
+ For example:
52
+
53
+ ```javascript
54
+ import Hello from "components/hello.svelte";
55
+ import WebpackerSvelte from "webpacker-svelte";
56
+ import Turbolinks from "turbolinks";
57
+
58
+ Turbolinks.start();
59
+
60
+ WebpackerSvelte.setup({ Hello });
61
+ ```
62
+
63
+ You may also load turbolinks in regular asset pipeline `application.js`:
64
+
65
+ ```javascript
66
+ //= require "turbolinks"
67
+ ```
68
+
69
+ In that case, make sure your packs are loaded _after_ `application.js`
70
+
71
+ Now you can render Svelte components from your views or your controllers.
72
+
73
+ ### Rendering from a view
74
+
75
+ Use the `svelte_component` helper. The first argument is your component's name, the second one is the `props`:
76
+
77
+ ```erb
78
+ <%= svelte_component('Hello', name: 'Svelte') %>
79
+ ```
80
+
81
+ You can pass a `tag` argument to render the Svelte component in another tag than the default `div`. All other arguments will be passed to `content_tag`:
82
+
83
+ ```erb
84
+ <%= svelte_component('Hello', { name: 'Svelte' }, tag: :span, class: 'my-custom-component') %>
85
+ # This will render <span class="my-custom-component" data-svelte-component="Hello" data-svelte-props="..."></span>
86
+ ```
87
+
88
+ ### Rendering from a controller
89
+
90
+ ```rb
91
+ class PageController < ApplicationController
92
+ def main
93
+ render svelte_component: 'Hello', props: { name: 'Svelte' }
94
+ end
95
+ end
96
+ ```
97
+
98
+ You can use the `tag_options` argument to change the generated HTML, similar to the `svelte_component` method above:
99
+
100
+ ```rb
101
+ render svelte_component: 'Hello', props: { name: 'Svelte' }, tag_options: { tag: :span, class: 'my-custom-component' }
102
+ ```
103
+
104
+ You can also pass any of the usual arguments to `render` in this call: `layout`, `status`, `content_type`, etc.
105
+
106
+ _Note: you need to have [Webpack process your code](https://github.com/rails/webpacker#binstubs) before it is available to the browser, either by manually running `./bin/webpack` or having the `./bin/webpack-watcher` process running._
107
+
108
+ ### Hot Module Replacement
109
+
110
+ **HRM isn't working for Svelte3 yet. See: https://github.com/sveltejs/svelte-loader/issues/74**
111
+
112
+ [HMR](https://webpack.js.org/concepts/hot-module-replacement/) allows to reload / add / remove modules live in the browser without
113
+ reloading the page. This allows any change you make to your Svelte components to be applied as soon as you save,
114
+ preserving their current state.
115
+
116
+ **Once svelte-loader supports HMR for Svelte 3:**
117
+
118
+ 1. Set up the webpack svelte loader `svelte` for HMR.
119
+
120
+ ```javascript
121
+ module.exports = {
122
+ test: /\.svelte$/,
123
+ use: [
124
+ {
125
+ loader: "svelte-loader",
126
+ options: {
127
+ // HMR isn't supported for Svelte3 yet
128
+ // https://github.com/sveltejs/svelte-loader/issues/74
129
+ hotReload: true
130
+ }
131
+ }
132
+ ]
133
+ };
134
+ ```
135
+
136
+ 1. Set up `webpack-dev-server` for HMR. This is easy, just switch `hmr: true` in your `webpacker.yml` for development!
137
+
138
+ 1. you now need to use `webpack-dev-server` (in place of `webpack` or `webpack-watcher`).
139
+
140
+ ## Development
141
+
142
+ To work on this gem locally, you first need to clone and setup [the example application](https://github.com/will-wow/svelte-on-rails).
143
+
144
+ Then you need to change the example app Gemfile to point to your local repository and run bundle afterwise:
145
+
146
+ ```ruby
147
+ gem 'webpacker-svelte', path: '~/code/webpacker-svelte/'
148
+ ```
149
+
150
+ Finally, you need to tell Yarn to use your local copy of the NPM module in this application, using [`yarn link`](https://yarnpkg.com/en/docs/cli/link):
151
+
152
+ ```
153
+ $ cd ~/code/webpacker-svelte/javascript/webpacker_svelte-npm-module/
154
+ $ yarn
155
+ $ cd dist/
156
+ $ yarn # compiles the code from src/ to dist/
157
+ $ yarn link
158
+ success Registered "webpacker-svelte".
159
+ info You can now run `yarn link "webpacker-svelte"` in the projects where you want to use this module and it will be used instead.
160
+ $ cd ~/code/svelte-on-rails/
161
+ $ yarn link webpacker-svelte
162
+ success Registered "webpacker-svelte".
163
+ ```
164
+
165
+ After launching `./bin/webpack-watcher` and `./bin/rails server` in your example app directory, you can now change the Ruby or Javascript code in your local `webpacker-svelte` repository, and test it immediately using the example app.
166
+
167
+ ## Testing
168
+
169
+ If you changed the local javascript package, first ensure it is build (see above).
170
+
171
+ To run the test suite:
172
+
173
+ ```sh
174
+ $ rake test
175
+ ```
176
+
177
+ If you change the javascript code, please ensure there are no style errors before committing:
178
+
179
+ ```sh
180
+ $ cd javascript/webpacker_svelte-npm-module/
181
+ $ yarn lint
182
+ ```
183
+
184
+ ## Contributing
185
+
186
+ Bug reports and pull requests are welcome on GitHub at https://github.com/will-wow/webpacker-svelte.
187
+ Please feel free to open issues about your needs and features you would like to be added.
188
+
189
+ ## Wishlist
190
+
191
+ - [ ] server-side rendering (#3)
192
+
193
+ ### Thanks
194
+
195
+ All credit to [@renchap](https://github.com/renchap) for [webpacker-react](https://github.com/renchap/webpacker-react), this is just a light re-write of that repo to support Svelte!
@@ -0,0 +1,34 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require "English"
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << "test"
7
+ t.libs << "lib"
8
+ t.test_files = FileList["test/**/*_test.rb"]
9
+ t.verbose = true
10
+ end
11
+
12
+ task default: :test
13
+
14
+ # webpacker:check_webpack_binstubs is looking for binstubs
15
+ # in the gem root directory. We need to disable it for our
16
+ # tests, as it tries to check they exist when loading the
17
+ # example app
18
+
19
+ task "webpacker:check_webpack_binstubs"
20
+ Rake::Task["webpacker:check_webpack_binstubs"].clear
21
+
22
+ namespace :example_app do
23
+ desc "Runs yarn in test/example_app"
24
+ task :yarn do
25
+ sh "cd test/example_app && yarn"
26
+ end
27
+
28
+ desc "Runs webpack in test/example_app"
29
+ task webpack: :yarn do
30
+ sh "cd test/example_app && RAILS_ENV=test ./bin/webpack"
31
+ end
32
+ end
33
+
34
+ Rake::Task["test"].enhance ["example_app:webpack"]
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-cayman
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "webpacker/svelte"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ {
2
+ "presets": [["env", {
3
+ "targets": {
4
+ "browsers": ["> 1%", "last 2 versions"]
5
+ }
6
+ }]]
7
+ }
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ extends: ['airbnb-base', 'prettier'],
3
+ rules: {
4
+ 'comma-dangle': ['error', 'never'],
5
+ 'import/no-unresolved': 'off',
6
+ 'import/no-extraneous-dependencies': 'off',
7
+ 'import/extensions': 'off',
8
+ 'no-console': 'off',
9
+ 'no-new': 'off',
10
+ semi: ['error', 'never']
11
+ },
12
+ env: {
13
+ browser: true,
14
+ node: true
15
+ }
16
+ }
@@ -0,0 +1,5 @@
1
+ # webpacker-svelte
2
+
3
+ Javascript part for the `webpacker_svelte` Ruby gem.
4
+
5
+ Please see the project homepage for more details : https://github.com/will-wow/webpacker-svelte
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "webpacker-svelte",
3
+ "version": "0.0.0",
4
+ "description": "Javascript",
5
+ "main": "index.js",
6
+ "homepage": "https://github.com/will-wow/webpacker-svelte",
7
+ "repository": "will-wow/webpacker-svelte",
8
+ "author": {
9
+ "name": "Will Ockelmann-Wagner",
10
+ "email": "will.ockelmann.wagner@gmail.com"
11
+ },
12
+ "peerDependencies": {
13
+ "svelte": ">= 3"
14
+ },
15
+ "files": [
16
+ "index.js",
17
+ "ujs.js"
18
+ ],
19
+ "scripts": {
20
+ "prepublish": "cd .. ; yarn run build"
21
+ },
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "webpack-merge": "^4.1.1"
25
+ }
26
+ }
@@ -0,0 +1,13 @@
1
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2
+ # yarn lockfile v1
3
+
4
+
5
+ lodash@^4.17.4:
6
+ version "4.17.4"
7
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
8
+
9
+ webpack-merge@^4.1.1:
10
+ version "4.1.1"
11
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555"
12
+ dependencies:
13
+ lodash "^4.17.4"
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "webpacker-svelte-build",
3
+ "private": true,
4
+ "scripts": {
5
+ "build": "babel src --out-dir dist",
6
+ "lint": "npm-run-all -c lint:*",
7
+ "lint:prettier": "prettier --check '**/*.{js,json,md,svelte}'",
8
+ "lint:eslint": "eslint src/",
9
+ "format": "npm-run-all -c format:*",
10
+ "format:eslint": "eslint --fix src/",
11
+ "format:prettier": "prettier --write '**/*.{js,json,md,svelte}'"
12
+ },
13
+ "devDependencies": {
14
+ "babel-cli": "^6.26.0",
15
+ "babel-preset-env": "^1.7.0",
16
+ "eslint": "^6.3.0",
17
+ "eslint-config-airbnb-base": "^14.0.0",
18
+ "eslint-config-prettier": "^6.2.0",
19
+ "eslint-plugin-import": "^2.18.2",
20
+ "npm-run-all": "^4.1.5",
21
+ "prettier": "^1.18.2"
22
+ },
23
+ "dependencies": {
24
+ "lodash": "^4.0.0"
25
+ }
26
+ }
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ semi: false,
3
+ singleQuote: true
4
+ }
@@ -0,0 +1,70 @@
1
+ import intersection from 'lodash/intersection'
2
+ import keys from 'lodash/keys'
3
+ import assign from 'lodash/assign'
4
+ import omit from 'lodash/omit'
5
+ import ujs from './ujs'
6
+
7
+ const CLASS_ATTRIBUTE_NAME = 'data-svelte-component'
8
+ const PROPS_ATTRIBUTE_NAME = 'data-svelte-props'
9
+
10
+ const noop = () => {}
11
+
12
+ const WebpackerSvelte = {
13
+ registeredComponents: {},
14
+
15
+ render(node, Component) {
16
+ const propsJson = node.getAttribute(PROPS_ATTRIBUTE_NAME)
17
+ const props = propsJson && JSON.parse(propsJson)
18
+
19
+ new Component({
20
+ target: node,
21
+ props
22
+ })
23
+ },
24
+
25
+ registerComponents(components) {
26
+ const collisions = intersection(
27
+ keys(this.registeredComponents),
28
+ keys(components)
29
+ )
30
+ if (collisions.length > 0) {
31
+ console.error(
32
+ `webpacker-svelte: can not register components. Following components are already registered: ${collisions}`
33
+ )
34
+ }
35
+
36
+ assign(this.registeredComponents, omit(components, collisions))
37
+ return true
38
+ },
39
+
40
+ mountComponents() {
41
+ const { registeredComponents } = this
42
+ const toMount = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}]`)
43
+
44
+ for (let i = 0; i < toMount.length; i += 1) {
45
+ const node = toMount[i]
46
+ const className = node.getAttribute(CLASS_ATTRIBUTE_NAME)
47
+ const component = registeredComponents[className]
48
+
49
+ if (component) {
50
+ if (node.innerHTML.length === 0) this.render(node, component)
51
+ } else {
52
+ console.error(
53
+ `webpacker-svelte: can not render a component that has not been registered: ${className}`
54
+ )
55
+ }
56
+ }
57
+ },
58
+
59
+ setup(components = {}) {
60
+ if (typeof window.WebpackerSvelte === 'undefined') {
61
+ window.WebpackerSvelte = this
62
+ ujs.setup(this.mountComponents.bind(this), noop)
63
+ }
64
+
65
+ window.WebpackerSvelte.registerComponents(components)
66
+ window.WebpackerSvelte.mountComponents()
67
+ }
68
+ }
69
+
70
+ export default WebpackerSvelte