webpacker-react 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b2bf95c452f63279e5f6ca108129cd39e7a9a0e
4
- data.tar.gz: 17f0a6a4b80916879c8c0a400aa6e38462f4ef93
3
+ metadata.gz: ab20541e11a8ca3cfda69b8359711dc6ec01b878
4
+ data.tar.gz: 44795485fe7bdec875cdc9975bfb5c79d036dcc0
5
5
  SHA512:
6
- metadata.gz: c7ef3bb80a1aa78f930deaf1c8defe431eba0d84f4329d3663ee563d51c8dd567ee2cb1da45bba9b17267011e98ccf4a221833f0217072b86ce354c8b59f7cbb
7
- data.tar.gz: a5ca92600867b135ed67e4c0dae9171ea79931259ac8f6f22b0e02224eed61f5c842c670e7d2a6cbf1cabee0cb8af58ad52a9a0c2e12513c7faec3607b07b6b9
6
+ metadata.gz: 89a2087cf23242199f588d80139f809fb35b87a5b3abc530bd7ad2ff0aea3c08c399a3bd7bd875b5cd5b2b7d7d1e5a7a19028bee27d7066ce523e007186fd409
7
+ data.tar.gz: b20d46ad6d1ac3dfb130aa6c691be91738b879ec4d457fa84f25f8a40f9bee175da743d5180f1af50cfd8f3abf5a8d6801ca6931a394f26a40543be033135a10
@@ -0,0 +1,9 @@
1
+ Fixes # .
2
+
3
+ Changes:
4
+
5
+ Please ensure that:
6
+ - [ ] Changelog is updated if not a minor patch
7
+ - [ ] Ruby linting is ok: `rubocop` is all green
8
+ - [ ] Javascript linting is ok: `cd javascript/webpacker_react-npm-module/ && yarn lint` is all green
9
+ - [ ] [Tests](https://github.com/renchap/webpacker-react#testing) are all green
@@ -0,0 +1,21 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [Unreleased]
8
+ ## 0.2.0 - 2017-03-20
9
+ ### Added
10
+ - support for Turbolinks 5, Turbolinks 2.4 and PJAX. Components will be mounted and unmounted when Turbolinks-specific events occur. Also, the integration works with Turbolinks 5 cache.
11
+ - New `WebpackerReact.setup({Component1, Component2, ...})` initialization API. The old API couldn't properly detect the components' names, thus user is required to provide the names in the configuration object's keys.
12
+ ### Removed
13
+ - `WebpackerReact.register(Component)` has been dropped in favor of `WebpackerReact.setup({Component})`
14
+ ## 0.1.0 - 2017-02-23
15
+ ### Added
16
+ - First released version
17
+ - render React components from views using the `react_component` helper
18
+ - render React components from controllers using `render react_component: 'name'` (#1 by @daninfpj)
19
+ - basic Hot Module Remplacement (#7 by @mfazekas)
20
+
21
+ [Unreleased]: https://github.com/renchap/webpacker-react/compare/v0.1.0...HEAD
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project maintainer at renchap@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/README.md CHANGED
@@ -22,20 +22,16 @@ Your Rails application needs to use Webpacker and have the React integration don
22
22
  First, you need to add the webpacker-react gem to your Rails app Gemfile:
23
23
 
24
24
  ```ruby
25
- gem 'webpacker-react', "~>0.1.0"
25
+ gem 'webpacker-react', "~> 0.1.0"
26
26
  ```
27
27
 
28
- Once done, run `bundler` to install the gem.
28
+ Once done, run `bundle` to install the gem.
29
29
 
30
- Then you need to update your `vendor/package.json` file to include the `webpacker-react` NPM module:
31
- ```json
32
- "dependencies": {
33
- "..."
34
- "webpacker-react": "~>0.1.0"
35
- },
36
- ```
30
+ Then you need to update your `package.json` file to include the `webpacker-react` NPM module:
31
+
32
+ `./bin/yarn add webpacker-react`
37
33
 
38
- Finally, run `./bin/yarn` to install the module. You are now all set!
34
+ You are now all set!
39
35
 
40
36
  ### Note about versions
41
37
 
@@ -50,9 +46,33 @@ In your pack file (`app/javascript/packs/*.js`), import your components as well
50
46
  import Hello from 'components/hello'
51
47
  import WebpackerReact from 'webpacker-react'
52
48
 
53
- WebpackerReact.register(Hello)
49
+ WebpackerReact.setup({Hello}) // ES6 shorthand for {Hello: Hello}
54
50
  ```
55
51
 
52
+ ### With Turbolinks
53
+
54
+ You have to make sure Turbolinks is loaded before calling `WebpackerReact.initialize()`.
55
+
56
+ For example:
57
+
58
+ ```javascript
59
+ import Hello from 'components/hello'
60
+ import WebpackerReact from 'webpacker-react'
61
+ import Turbolinks from 'turbolinks'
62
+
63
+ Turbolinks.start()
64
+
65
+ WebpackerReact.setup({Hello})
66
+ ```
67
+
68
+ You may also load turbolinks in regular asset pipeline `application.js`:
69
+
70
+ ```javascript
71
+ //= require "turbolinks"
72
+ ```
73
+
74
+ In that case, make sure your packs are loaded *after* `application.js`
75
+
56
76
  Now you can render React components from your views or your controllers.
57
77
 
58
78
  ### Rendering from a view
@@ -101,7 +121,7 @@ significantly different than the standard Webpacker config:
101
121
  var configureHotModuleReplacement = require('webpacker-react/configure-hot-module-replacement')
102
122
 
103
123
  var sharedConfig = require('./shared.js')
104
- sharedConfig = configureHotModuleReplacement(sharedConfig)
124
+ sharedConfig.config = configureHotModuleReplacement(sharedConfig.config)
105
125
 
106
126
  module.exports = merge(sharedConfig, ...)
107
127
  ```
@@ -160,7 +180,7 @@ and start `webpack-dev-server` in hot replacement mode:
160
180
  import SomeRootReactComponent from 'components/some-root-react-component'
161
181
  import WebpackerReact from 'webpacker-react/hmr'
162
182
 
163
- WebpackerReact.register(SomeRootReactComponent)
183
+ WebpackerReact.setup({SomeRootReactComponent})
164
184
  if (module.hot)
165
185
  module.hot.accept('components/some-root-react-component', () =>
166
186
  WebpackerReact.renderOnHMR(SomeRootReactComponent) )
@@ -179,12 +199,15 @@ gem 'webpacker-react', path: '~/code/webpacker-react/'
179
199
  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):
180
200
 
181
201
  ```
182
- $ cd ~/code/webpacker-react/javascript/webpacker_react-npm-module/dist/
183
- $ yarn # builds the code
202
+ $ cd ~/code/webpacker-react/javascript/webpacker_react-npm-module/
203
+ $ yarn
204
+ $ cd dist/
205
+ $ yarn # compiles the code from src/ to dist/
184
206
  $ yarn link
185
207
  success Registered "webpacker-react".
186
208
  info You can now run `yarn link "webpacker-react"` in the projects where you want to use this module and it will be used instead.
187
209
  $ cd ~/code/webpacker-react-example/
210
+ $ yarn link webpacker-react
188
211
  success Registered "webpacker-react".
189
212
  ```
190
213
 
@@ -212,6 +235,13 @@ Finally, run the test suite:
212
235
  $ rake test
213
236
  ```
214
237
 
238
+ If you change the javascript code, please ensure there are no style errors:
239
+
240
+ ```sh
241
+ $ cd javascript/webpacker_react-npm-module/
242
+ $ yarn lint
243
+ ```
244
+
215
245
  ## Contributing
216
246
 
217
247
  Bug reports and pull requests are welcome on GitHub at https://github.com/renchap/webpacker-react.
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-cayman
data/circle.yml CHANGED
@@ -9,9 +9,13 @@ checkout:
9
9
  pwd: javascript/webpacker_react-npm-module/dist
10
10
  - yarn link:
11
11
  pwd: javascript/webpacker_react-npm-module/dist
12
- test:
13
- pre:
12
+ compile:
13
+ override:
14
14
  - test/example_app/bin/yarn
15
15
  - yarn link webpacker-react:
16
16
  pwd: test/example_app/vendor
17
17
  - test/example_app/bin/webpack
18
+ test:
19
+ pre:
20
+ - yarn lint:
21
+ pwd: javascript/webpacker_react-npm-module
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ 'extends': 'airbnb',
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
+ semi: ['error', 'never'],
10
+ },
11
+ 'env': {
12
+ 'browser': true,
13
+ 'node': true,
14
+ },
15
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpacker-react",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Javascript",
5
5
  "main": "index.js",
6
6
  "homepage": "https://github.com/renchap/webpacker-react",
@@ -2,10 +2,19 @@
2
2
  "name": "webpacker-react-build",
3
3
  "private": true,
4
4
  "scripts": {
5
- "build": "babel src --presets=babel-preset-es2015 --out-dir dist"
5
+ "build": "babel src --presets=babel-preset-es2015 --out-dir dist",
6
+ "lint": "eslint src/"
6
7
  },
7
8
  "devDependencies": {
8
9
  "babel-cli": "^6.18.0",
9
- "babel-preset-es2015": "^6.18.0"
10
+ "babel-preset-es2015": "^6.22.0",
11
+ "eslint": "^3.16.1",
12
+ "eslint-config-airbnb": "^14.1.0",
13
+ "eslint-plugin-import": "^2.2.0",
14
+ "eslint-plugin-jsx-a11y": "^4.0.0",
15
+ "eslint-plugin-react": "^6.10.0"
16
+ },
17
+ "dependencies": {
18
+ "lodash": "^4.0.0"
10
19
  }
11
20
  }
@@ -1,13 +1,14 @@
1
1
  import webpack from 'webpack'
2
2
  import merge from 'webpack-merge'
3
3
 
4
- function configureHotModuleReplacement(config) {
5
- let webpackDevServerAddr = process.env['WEBPACK_DEV_SERVER_ADDR'] || 'http://localhost:8080/'
6
- config = merge(
7
- config,
4
+ function configureHotModuleReplacement(originalConfig) {
5
+ const webpackDevServerAddr = process.env.WEBPACK_DEV_SERVER_ADDR || 'http://localhost:8080/'
6
+ const config = merge(
7
+ originalConfig,
8
8
  {
9
9
  output: {
10
- publicPath: webpackDevServerAddr // needed for HMR to know where to load the hot update chunks
10
+ // needed for HMR to know where to load the hot update chunks
11
+ publicPath: webpackDevServerAddr
11
12
  },
12
13
  plugins: [
13
14
  new webpack.NamedModulesPlugin()
@@ -15,20 +16,19 @@ function configureHotModuleReplacement(config) {
15
16
  }
16
17
  )
17
18
 
18
- config.module.rules = config.module.rules.map( rule => {
19
+ config.module.rules = config.module.rules.map((rule) => {
19
20
  if (rule.loader === 'babel-loader') {
20
- return merge(rule, {options: {plugins: ['react-hot-loader/babel']}})
21
- } else {
22
- return rule
21
+ return merge(rule, { options: { plugins: ['react-hot-loader/babel'] } })
23
22
  }
23
+ return rule
24
24
  })
25
25
 
26
- for (let key of Object.keys(config.entry)) {
26
+ Object.keys(config.entry).forEach((key) => {
27
27
  if (!(config.entry[key] instanceof Array)) {
28
28
  config.entry[key] = [config.entry[key]]
29
29
  }
30
30
  config.entry[key].unshift('react-hot-loader/patch')
31
- }
31
+ })
32
32
  return config
33
33
  }
34
34
 
@@ -2,8 +2,8 @@ import { AppContainer } from 'react-hot-loader'
2
2
  import WebpackerReact from 'webpacker-react'
3
3
  import React from 'react'
4
4
 
5
- WebpackerReact.registerWrapForHMR( (reactElement) => {
6
- return React.createElement(AppContainer, {}, reactElement)
7
- })
5
+ WebpackerReact.registerWrapForHMR(reactElement =>
6
+ React.createElement(AppContainer, {}, reactElement)
7
+ )
8
8
 
9
9
  export default WebpackerReact
@@ -1,17 +1,18 @@
1
1
  import React from 'react'
2
2
  import ReactDOM from 'react-dom'
3
+ import { intersection, keys, assign, omit } from 'lodash'
4
+ import ujs from './ujs'
3
5
 
4
6
  const CLASS_ATTRIBUTE_NAME = 'data-react-class'
5
7
  const PROPS_ATTRIBUTE_NAME = 'data-react-props'
6
8
 
7
- var WebpackerReact = {
8
- eventsRegistered: false,
9
- registeredComponents : {},
9
+ const WebpackerReact = {
10
+ registeredComponents: {},
10
11
  wrapForHMR: null,
11
12
 
12
- render: function(node, component) {
13
- var propsJson = node.getAttribute(PROPS_ATTRIBUTE_NAME)
14
- var props = propsJson && JSON.parse(propsJson)
13
+ render(node, component) {
14
+ const propsJson = node.getAttribute(PROPS_ATTRIBUTE_NAME)
15
+ const props = propsJson && JSON.parse(propsJson)
15
16
 
16
17
  let reactElement = React.createElement(component, props)
17
18
  if (this.wrapForHMR) {
@@ -20,17 +21,18 @@ var WebpackerReact = {
20
21
  ReactDOM.render(reactElement, node)
21
22
  },
22
23
 
23
- renderOnHMR: function(component) {
24
- var name = component.name
24
+ renderOnHMR(component) {
25
+ const name = component.name
26
+
25
27
  this.registeredComponents[name] = component
26
28
 
27
29
  if (!this.wrapForHMR) {
28
- console.warn('webpack-react: renderOnHMR called but not elements not wrapped for HMR')
30
+ console.warn('webpacker-react: renderOnHMR called but not elements not wrapped for HMR')
29
31
  }
30
32
 
31
- var toMount = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}=${name}]`)
32
- for (var i = 0; i < toMount.length; ++i) {
33
- var node = toMount[i]
33
+ const toMount = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}=${name}]`)
34
+ for (let i = 0; i < toMount.length; i += 1) {
35
+ const node = toMount[i]
34
36
 
35
37
  this.render(node, component)
36
38
  }
@@ -40,47 +42,49 @@ var WebpackerReact = {
40
42
  this.wrapForHMR = wrapForHMR
41
43
  },
42
44
 
43
- register: function(component) {
44
- var name = component.name
45
-
46
- if (this.registeredComponents[name]) {
47
- console.warn('webpacker-react: Cant register component, another one with this name is already registered: ' + name)
48
- return false
45
+ registerComponents(components) {
46
+ const collisions = intersection(keys(this.registeredComponents), keys(components))
47
+ if (collisions.length > 0) {
48
+ console.error(`webpacker-react: can not register components. Following components are already registered: ${collisions}`)
49
49
  }
50
50
 
51
- this.registeredComponents[name] = component
51
+ assign(this.registeredComponents, omit(components, collisions))
52
52
  return true
53
53
  },
54
54
 
55
- addEventEventhandlers: function() {
56
- var registeredComponents = this.registeredComponents
57
-
58
- if (this.eventsRegistered == true) {
59
- console.warn("webpacker-react: events have already been registered")
60
- return false
55
+ unmountComponents() {
56
+ const mounted = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}]`)
57
+ for (let i = 0; i < mounted.length; i += 1) {
58
+ ReactDOM.unmountComponentAtNode(mounted[i])
61
59
  }
60
+ },
62
61
 
63
- document.addEventListener("DOMContentLoaded", () => {
64
- var toMount = document.querySelectorAll('[' + CLASS_ATTRIBUTE_NAME + ']')
62
+ mountComponents() {
63
+ const registeredComponents = this.registeredComponents
64
+ const toMount = document.querySelectorAll(`[${CLASS_ATTRIBUTE_NAME}]`)
65
65
 
66
- for (var i = 0; i < toMount.length; ++i) {
67
- var node = toMount[i]
68
- var className = node.getAttribute(CLASS_ATTRIBUTE_NAME)
69
- var component = registeredComponents[className]
66
+ for (let i = 0; i < toMount.length; i += 1) {
67
+ const node = toMount[i]
68
+ const className = node.getAttribute(CLASS_ATTRIBUTE_NAME)
69
+ const component = registeredComponents[className]
70
70
 
71
- if (component) {
72
- this.render(node, component)
73
- } else {
74
- console.error('webpacker-react: cant render a component that has not been registered: ' + className)
75
- }
71
+ if (component) {
72
+ if (node.innerHTML.length === 0) this.render(node, component)
73
+ } else {
74
+ console.error(`webpacker-react: cant render a component that has not been registered: ${className}`)
76
75
  }
77
- });
76
+ }
77
+ },
78
78
 
79
- this.eventsRegistered = true
80
- return true
81
- }
82
- };
79
+ setup(components = {}) {
80
+ if (typeof window.WebpackerReact === 'undefined') {
81
+ window.WebpackerReact = this
82
+ ujs.setup(this.mountComponents.bind(this), this.unmountComponents.bind(this))
83
+ }
83
84
 
84
- WebpackerReact.addEventEventhandlers()
85
+ window.WebpackerReact.registerComponents(components)
86
+ window.WebpackerReact.mountComponents()
87
+ }
88
+ }
85
89
 
86
90
  export default WebpackerReact