webpacker-jets 3.2.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +4 -0
  3. data/.eslintrc.js +14 -0
  4. data/.gitignore +6 -0
  5. data/.rubocop.yml +124 -0
  6. data/.travis.yml +32 -0
  7. data/CHANGELOG.md +523 -0
  8. data/Gemfile +13 -0
  9. data/Gemfile.lock +154 -0
  10. data/MIT-LICENSE +20 -0
  11. data/README.md +445 -0
  12. data/Rakefile +12 -0
  13. data/docs/assets.md +106 -0
  14. data/docs/cloud9.md +310 -0
  15. data/docs/css.md +116 -0
  16. data/docs/deployment.md +74 -0
  17. data/docs/docker.md +49 -0
  18. data/docs/env.md +65 -0
  19. data/docs/es6.md +53 -0
  20. data/docs/folder-structure.md +66 -0
  21. data/docs/misc.md +23 -0
  22. data/docs/props.md +223 -0
  23. data/docs/testing.md +128 -0
  24. data/docs/troubleshooting.md +119 -0
  25. data/docs/typescript.md +116 -0
  26. data/docs/webpack-dev-server.md +92 -0
  27. data/docs/webpack.md +297 -0
  28. data/docs/yarn.md +12 -0
  29. data/exe/webpack +8 -0
  30. data/exe/webpack-dev-server +8 -0
  31. data/gemfiles/Gemfile-rails-edge +13 -0
  32. data/gemfiles/Gemfile-rails.4.2.x +10 -0
  33. data/gemfiles/Gemfile-rails.5.0.x +10 -0
  34. data/gemfiles/Gemfile-rails.5.1.x +10 -0
  35. data/lib/install/angular.rb +27 -0
  36. data/lib/install/coffee.rb +22 -0
  37. data/lib/install/config/.babelrc +18 -0
  38. data/lib/install/config/.postcssrc.yml +3 -0
  39. data/lib/install/config/webpack/development.js +3 -0
  40. data/lib/install/config/webpack/environment.js +3 -0
  41. data/lib/install/config/webpack/production.js +3 -0
  42. data/lib/install/config/webpack/staging.js +3 -0
  43. data/lib/install/config/webpack/test.js +3 -0
  44. data/lib/install/config/webpacker.yml +79 -0
  45. data/lib/install/elm.rb +38 -0
  46. data/lib/install/erb.rb +22 -0
  47. data/lib/install/examples/angular/hello_angular.js +7 -0
  48. data/lib/install/examples/angular/hello_angular/app/app.component.ts +9 -0
  49. data/lib/install/examples/angular/hello_angular/app/app.module.ts +16 -0
  50. data/lib/install/examples/angular/hello_angular/index.ts +8 -0
  51. data/lib/install/examples/angular/hello_angular/polyfills.ts +73 -0
  52. data/lib/install/examples/angular/tsconfig.json +19 -0
  53. data/lib/install/examples/coffee/hello_coffee.coffee +4 -0
  54. data/lib/install/examples/elm/Main.elm +54 -0
  55. data/lib/install/examples/elm/hello_elm.js +12 -0
  56. data/lib/install/examples/erb/hello_erb.js.erb +6 -0
  57. data/lib/install/examples/react/.babelrc +6 -0
  58. data/lib/install/examples/react/hello_react.jsx +26 -0
  59. data/lib/install/examples/vue/app.vue +22 -0
  60. data/lib/install/examples/vue/hello_vue.js +70 -0
  61. data/lib/install/javascript/packs/application.js +10 -0
  62. data/lib/install/loaders/coffee.js +6 -0
  63. data/lib/install/loaders/elm.js +23 -0
  64. data/lib/install/loaders/erb.js +11 -0
  65. data/lib/install/loaders/typescript.js +6 -0
  66. data/lib/install/loaders/vue.js +13 -0
  67. data/lib/install/react.rb +28 -0
  68. data/lib/install/template.rb +37 -0
  69. data/lib/install/vue.rb +26 -0
  70. data/lib/tasks/installers.rake +24 -0
  71. data/lib/tasks/webpacker.rake +22 -0
  72. data/lib/tasks/webpacker/check_binstubs.rake +12 -0
  73. data/lib/tasks/webpacker/check_node.rake +24 -0
  74. data/lib/tasks/webpacker/check_yarn.rake +24 -0
  75. data/lib/tasks/webpacker/clobber.rake +16 -0
  76. data/lib/tasks/webpacker/compile.rake +41 -0
  77. data/lib/tasks/webpacker/install.rake +13 -0
  78. data/lib/tasks/webpacker/verify_install.rake +16 -0
  79. data/lib/tasks/webpacker/yarn_install.rake +6 -0
  80. data/lib/webpacker.rb +32 -0
  81. data/lib/webpacker/commands.rb +23 -0
  82. data/lib/webpacker/compiler.rb +88 -0
  83. data/lib/webpacker/configuration.rb +87 -0
  84. data/lib/webpacker/dev_server.rb +61 -0
  85. data/lib/webpacker/dev_server_proxy.rb +26 -0
  86. data/lib/webpacker/dev_server_runner.rb +51 -0
  87. data/lib/webpacker/helper.rb +66 -0
  88. data/lib/webpacker/instance.rb +44 -0
  89. data/lib/webpacker/manifest.rb +75 -0
  90. data/lib/webpacker/railtie.rb +82 -0
  91. data/lib/webpacker/rake_tasks.rb +6 -0
  92. data/lib/webpacker/runner.rb +22 -0
  93. data/lib/webpacker/version.rb +9 -0
  94. data/lib/webpacker/webpack_runner.rb +15 -0
  95. data/package.json +67 -0
  96. data/package/__tests__/environment.js +74 -0
  97. data/package/config.js +34 -0
  98. data/package/config_types/__tests__/config_list.js +123 -0
  99. data/package/config_types/__tests__/config_object.js +43 -0
  100. data/package/config_types/config_list.js +85 -0
  101. data/package/config_types/config_object.js +55 -0
  102. data/package/config_types/index.js +7 -0
  103. data/package/environment.js +116 -0
  104. data/package/environments/development.js +46 -0
  105. data/package/environments/production.js +37 -0
  106. data/package/environments/test.js +3 -0
  107. data/package/index.js +20 -0
  108. data/package/rules/babel.js +13 -0
  109. data/package/rules/css.js +39 -0
  110. data/package/rules/file.js +13 -0
  111. data/package/rules/index.js +11 -0
  112. data/package/rules/sass.js +15 -0
  113. data/package/utils/__tests__/deep_assign.js +11 -0
  114. data/package/utils/__tests__/deep_merge.js +10 -0
  115. data/package/utils/__tests__/objectify.js +9 -0
  116. data/package/utils/deep_assign.js +22 -0
  117. data/package/utils/deep_merge.js +23 -0
  118. data/package/utils/helpers.js +32 -0
  119. data/package/utils/objectify.js +4 -0
  120. data/test/command_test.rb +27 -0
  121. data/test/compiler_test.rb +35 -0
  122. data/test/configuration_test.rb +69 -0
  123. data/test/dev_server_test.rb +24 -0
  124. data/test/helper_test.rb +52 -0
  125. data/test/manifest_test.rb +28 -0
  126. data/test/rake_tasks_test.rb +29 -0
  127. data/test/test_app/Rakefile +3 -0
  128. data/test/test_app/app/javascript/packs/application.js +10 -0
  129. data/test/test_app/config/application.rb +11 -0
  130. data/test/test_app/config/environment.rb +4 -0
  131. data/test/test_app/config/webpacker.yml +65 -0
  132. data/test/test_app/public/packs/manifest.json +6 -0
  133. data/test/test_helper.rb +29 -0
  134. data/webpacker-jets.gemspec +29 -0
  135. data/yarn.lock +5768 -0
  136. metadata +250 -0
@@ -0,0 +1,74 @@
1
+ # Deployment
2
+
3
+
4
+ Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`.
5
+ If you are not using Sprockets `webpacker:compile` is automatically aliased to `assets:precompile`. Remember to set NODE_ENV environment variable to production during deployment or when running the rake task.
6
+
7
+ The `javascript_pack_tag` and `stylesheet_pack_tag` helper method will automatically insert the correct HTML tag for compiled pack. Just like the asset pipeline does it.
8
+
9
+ By default the output will look like this in different environments:
10
+
11
+ ```html
12
+ <!-- In development mode with webpack-dev-server -->
13
+ <script src="http://localhost:8080/calendar-0bd141f6d9360cf4a7f5.js"></script>
14
+ <link rel="stylesheet" media="screen" href="http://localhost:8080/calendar-dc02976b5f94b507e3b6.css">
15
+ <!-- In production or development mode -->
16
+ <script src="/packs/calendar-0bd141f6d9360cf4a7f5.js"></script>
17
+ <link rel="stylesheet" media="screen" href="/packs/calendar-dc02976b5f94b507e3b6.css">
18
+ ```
19
+
20
+
21
+ ## Heroku
22
+
23
+ Heroku installs Yarn and node by default if you deploy a Rails app with
24
+ Webpacker so all you would need to do:
25
+
26
+ ```bash
27
+ heroku create shiny-webpacker-app
28
+ heroku addons:create heroku-postgresql:hobby-dev
29
+ git push heroku master
30
+ ```
31
+
32
+
33
+ ## Nginx
34
+
35
+ Webpacker doesn't serve anything in production. You’re expected to configure your web server to serve files in public/ directly.
36
+
37
+ Some servers support sending precompressed versions of files with the `.gz` extension when they're available. For example, nginx offers a `gzip_static` directive.
38
+
39
+ Here's a sample nginx site config for a Rails app using Webpacker:
40
+
41
+ ```nginx
42
+ upstream app {
43
+ # ...
44
+ }
45
+
46
+ server {
47
+ server_name www.example.com;
48
+ root /path/to/app/public;
49
+
50
+ location @app {
51
+ proxy_pass http://app;
52
+ proxy_redirect off;
53
+
54
+ proxy_set_header Host $host;
55
+ proxy_set_header X-Real-IP $remote_addr;
56
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
57
+ proxy_set_header X-Forwarded-Proto $scheme;
58
+ }
59
+
60
+ location / {
61
+ try_files $uri @app;
62
+ }
63
+
64
+ location ^~ /packs/ {
65
+ gzip_static on;
66
+ expires max;
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## CDN
72
+
73
+ Webpacker out-of-the-box provides CDN support using your Rails app `config.action_controller.asset_host` setting. If you already have [CDN](http://guides.rubyonrails.org/asset_pipeline.html#cdns) added in your Rails app
74
+ you don't need to do anything extra for Webpacker, it just works.
data/docs/docker.md ADDED
@@ -0,0 +1,49 @@
1
+ # Docker
2
+
3
+ To setup webpacker with a dockerized Rails application is trivial.
4
+
5
+ First, add a new service for webpacker in docker-compose.yml:
6
+
7
+ ```Dockerfile
8
+ version: '3'
9
+ services:
10
+ webpacker:
11
+ build: .
12
+ env_file:
13
+ - '.env.docker'
14
+ command: bundle exec webpack-dev-server
15
+ volumes:
16
+ - .:/webpacker-example-app
17
+ ports:
18
+ - '3035:3035'
19
+ ```
20
+
21
+ add nodejs and yarn as dependencies in Dockerfile,
22
+
23
+ ```dockerfile
24
+ FROM ruby:2.4.1
25
+ RUN apt-get update -qq
26
+
27
+ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
28
+ RUN curl -sL https://deb.nodesource.com/setup_8.x | bash
29
+ RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
30
+
31
+ RUN apt-get install -y nodejs
32
+ RUN apt-get update && apt-get install yarn
33
+
34
+ # Rest of the commands....
35
+ ```
36
+
37
+ and create an env file to load environment variables from:
38
+
39
+ ```env
40
+ NODE_ENV=development
41
+ RAILS_ENV=development
42
+ WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
43
+ ```
44
+
45
+ Lastly, rebuild your container:
46
+
47
+ ```bash
48
+ docker-compose up --build
49
+ ```
data/docs/env.md ADDED
@@ -0,0 +1,65 @@
1
+ # Environment variables
2
+
3
+
4
+ Environment variables are supported out of the box in Webpacker. For example if
5
+ you run the webpack dev server like so:
6
+ ```
7
+ FOO=hello BAR=world ./bin/webpack-dev-server
8
+ ```
9
+
10
+ You can then reference these variables in your JavaScript app code with
11
+ `process.env`:
12
+
13
+ ```js
14
+ console.log(process.env.FOO) // Compiles to console.log("hello")
15
+ ```
16
+
17
+ You may want to store configuration in environment variables via `.env` files,
18
+ similar to the [dotenv Ruby gem](https://github.com/bkeepers/dotenv).
19
+
20
+ In development, if you use [Foreman](http://ddollar.github.io/foreman) or [Invoker](http://invoker.codemancers.com)
21
+ to launch the webpack server, both of these tools have basic support for a
22
+ `.env` file (Invoker also supports `.env.local`), so no further configuration
23
+ is needed.
24
+
25
+ However, if you run the webpack server without Foreman/Invoker, or if you
26
+ want more control over what `.env` files to load, you can use the
27
+ [dotenv npm package](https://github.com/motdotla/dotenv). Here is what you could
28
+ do to support a "Ruby-like" dotenv:
29
+
30
+ ```
31
+ yarn add dotenv
32
+ ```
33
+
34
+ ```javascript
35
+ // config/webpack/environment.js
36
+
37
+ ...
38
+ const { environment } = require('@rails/webpacker')
39
+ const webpack = require('webpack')
40
+ const dotenv = require('dotenv')
41
+
42
+ const dotenvFiles = [
43
+ `.env.${process.env.NODE_ENV}.local`,
44
+ '.env.local',
45
+ `.env.${process.env.NODE_ENV}`,
46
+ '.env'
47
+ ]
48
+ dotenvFiles.forEach((dotenvFile) => {
49
+ dotenv.config({ path: dotenvFile, silent: true })
50
+ })
51
+
52
+ environment.plugins.set('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
53
+
54
+ module.exports = environment
55
+ ```
56
+
57
+ **Warning:** using Foreman/Invoker and npm dotenv at the same time can result in
58
+ confusing behavior, in that Foreman/Invoker variables take precedence over
59
+ npm dotenv variables.
60
+
61
+ If you'd like to pass custom variables to the on demand compiler, use `Webpacker::Compiler.env` attribute.
62
+
63
+ ```rb
64
+ Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
65
+ ```
data/docs/es6.md ADDED
@@ -0,0 +1,53 @@
1
+ # ES6
2
+
3
+
4
+ ## Babel
5
+
6
+ Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
7
+ you can use next generation JavaScript, today. The Webpacker installer sets up a
8
+ standard `.babelrc` file in your app root, which will work great in most cases
9
+ because of [babel-env-preset](https://github.com/babel/babel-preset-env).
10
+
11
+ Following ES6/7 features are supported out of the box:
12
+
13
+ * Async/await.
14
+ * Object Rest/Spread Properties.
15
+ * Exponentiation Operator.
16
+ * Dynamic import() - useful for route level code-splitting
17
+ * Class Fields and Static Properties.
18
+
19
+ We have also included [babel polyfill](https://babeljs.io/docs/usage/polyfill/)
20
+ that includes a custom regenerator runtime and core-js.
21
+
22
+ Don't forget to import `babel-polyfill` in your main entry point like so:
23
+
24
+ ```js
25
+ import "babel-polyfill"
26
+ ```
27
+
28
+
29
+ ## Module import() vs require()
30
+
31
+ While you are free to use `require()` and `module.exports`, we encourage you
32
+ to use `import` and `export` instead since it reads and looks much better.
33
+
34
+ ```js
35
+ import Button from 'react-bootstrap/lib/Button'
36
+
37
+ // or
38
+ import { Button } from 'react-bootstrap'
39
+
40
+ class Foo {
41
+ // code...
42
+ }
43
+
44
+ export default Foo
45
+ import Foo from './foo'
46
+ ```
47
+
48
+ You can also use named export and import
49
+
50
+ ```js
51
+ export const foo = () => console.log('hello world')
52
+ import { foo } from './foo'
53
+ ```
@@ -0,0 +1,66 @@
1
+ # Folder Structure
2
+
3
+
4
+ ## Packs a.k.a webpack entries
5
+
6
+ "Packs" is a special directory made only for webpack entry files so don't put anything
7
+ here that you don't want to link in your views.
8
+
9
+
10
+ ## Source
11
+
12
+ You can put your app source under `app/javascript` folder or whatever you have configured
13
+ in `config/webpacker.yml`.
14
+
15
+
16
+ ## Example
17
+
18
+ Let's say you're building a calendar app. Your JS app structure could look like this:
19
+
20
+ ```js
21
+ // app/javascript/packs/calendar.js
22
+
23
+ import 'calendar'
24
+ ```
25
+
26
+ ```
27
+ app/javascript/calendar/index.js // gets loaded by import 'calendar'
28
+ app/javascript/calendar/components/grid.jsx
29
+ app/javascript/calendar/styles/grid.sass
30
+ app/javascript/calendar/models/month.js
31
+ ```
32
+
33
+ ```erb
34
+ <%# app/views/layouts/application.html.erb %>
35
+
36
+ <%= javascript_pack_tag 'calendar' %>
37
+ <%= stylesheet_pack_tag 'calendar' %>
38
+ ```
39
+
40
+ But it could also look a million other ways.
41
+
42
+
43
+ ## Namespacing
44
+
45
+ You can also namespace your packs using directories similar to a Rails app.
46
+
47
+ ```
48
+ app/javascript/packs/admin/orders.js
49
+ app/javascript/packs/shop/orders.js
50
+ ```
51
+
52
+ and reference them in your views like this:
53
+
54
+ ```erb
55
+ <%# app/views/admin/orders/index.html.erb %>
56
+
57
+ <%= javascript_pack_tag 'admin/orders' %>
58
+ ```
59
+
60
+ and
61
+
62
+ ```erb
63
+ <%# app/views/shop/orders/index.html.erb %>
64
+
65
+ <%= javascript_pack_tag 'shop/orders' %>
66
+ ```
data/docs/misc.md ADDED
@@ -0,0 +1,23 @@
1
+ # How-Tos
2
+
3
+
4
+ ## Ignoring swap files
5
+
6
+ If you are using vim or emacs and want to ignore certain files you can add `ignore-loader`:
7
+
8
+ ```
9
+ yarn add ignore-loader
10
+ ```
11
+
12
+ and add `ignore-loader` to `config/webpack/environment.js`
13
+
14
+ ```js
15
+ // ignores vue~ swap files
16
+ const { environment } = require('@rails/webpacker')
17
+ environment.loaders.set('ignore', {
18
+ test: /.vue~$/,
19
+ loader: 'ignore-loader'
20
+ })
21
+ ```
22
+
23
+ And now all files with `.vue~` will be ignored by the webpack compiler.
data/docs/props.md ADDED
@@ -0,0 +1,223 @@
1
+ # Props
2
+
3
+
4
+ ## React
5
+
6
+ If you need more advanced React-integration, like server rendering, redux, or react-router, see [shakacode/react_on_rails](https://github.com/shakacode/react_on_rails), [react-rails](https://github.com/reactjs/react-rails), and [webpacker-react](https://github.com/renchap/webpacker-react).
7
+
8
+ If you're not concerned with view helpers to pass props or server rendering, can do it yourself:
9
+
10
+ ```erb
11
+ <%# views/layouts/application.html.erb %>
12
+
13
+ <%= content_tag :div,
14
+ id: "hello-react",
15
+ data: {
16
+ message: 'Hello!',
17
+ name: 'David'
18
+ }.to_json do %>
19
+ <% end %>
20
+ ```
21
+
22
+ ```js
23
+ // app/javascript/packs/hello_react.js
24
+
25
+ const Hello = props => (
26
+ <div className='react-app-wrapper'>
27
+ <img src={clockIcon} alt="clock" />
28
+ <h5 className='hello-react'>
29
+ {props.message} {props.name}!
30
+ </h5>
31
+ </div>
32
+ )
33
+
34
+ // Render component with data
35
+ document.addEventListener('DOMContentLoaded', () => {
36
+ const node = document.getElementById('hello-react')
37
+ const data = JSON.parse(node.getAttribute('data'))
38
+
39
+ ReactDOM.render(<Hello {...data} />, node)
40
+ })
41
+ ```
42
+
43
+
44
+ ## Vue
45
+
46
+ Add the data as attributes in the element you are going to use (or any other element for that matter).
47
+
48
+ ```erb
49
+ <%= content_tag :div,
50
+ id: "hello-vue",
51
+ data: {
52
+ message: "Hello!",
53
+ name: "David"
54
+ }.to_json do %>
55
+ <% end %>
56
+ ```
57
+
58
+ This should produce the following HTML:
59
+
60
+ ```html
61
+ <div id="hello-vue" data="{&quot;message&quot;:&quot;Hello!&quot;,&quot;name&quot;:&quot;David&quot;}"></div>
62
+ ```
63
+
64
+ Now, modify your Vue app to expect the properties.
65
+
66
+ ```html
67
+ <template>
68
+ <div id="app">
69
+ <p>{{test}}{{message}}{{name}}</p>
70
+ </div>
71
+ </template>
72
+
73
+ <script>
74
+ export default {
75
+ // A child component needs to explicitly declare
76
+ // the props it expects to receive using the props option
77
+ // See https://vuejs.org/v2/guide/components.html#Props
78
+ props: ["message","name"],
79
+ data: function () {
80
+ return {
81
+ test: 'This will display: '
82
+ }
83
+ }
84
+ }
85
+ </script>
86
+
87
+ <style>
88
+ </style>
89
+
90
+ ```
91
+
92
+ ```js
93
+ document.addEventListener('DOMContentLoaded', () => {
94
+ // Get the properties BEFORE the app is instantiated
95
+ const node = document.getElementById('hello-vue')
96
+ const props = JSON.parse(node.getAttribute('data'))
97
+
98
+ // Render component with props
99
+ new Vue({
100
+ render: h => h(App, { props })
101
+ }).$mount('#hello-vue');
102
+ })
103
+ ```
104
+
105
+ You can follow same steps for Angular too.
106
+
107
+
108
+ ## Elm
109
+
110
+ Just like with other implementations, we'll render our data inside a `data`
111
+ attribute:
112
+
113
+ ```erb
114
+ <%= content_tag :div,
115
+ id: "hello-elm",
116
+ data: {
117
+ message: "Hello",
118
+ name: "David"
119
+ }.to_json do %>
120
+ <% end %>
121
+ ```
122
+
123
+ We parse the JSON data and pass it to Elm as flags:
124
+
125
+ ```js
126
+ import Elm from '../Main'
127
+
128
+ document.addEventListener('DOMContentLoaded', () => {
129
+ const node = document.getElementById('hello-elm')
130
+ const data = JSON.parse(node.getAttribute('data'))
131
+ Elm.Main.embed(node, data)
132
+ })
133
+ ```
134
+
135
+ Defining `Flags` as a `type alias`, we instruct Elm to demand flags `message`
136
+ and `name` of type `String` on initialization.
137
+
138
+ Using `programWithFlags` we bring all the pieces together:
139
+
140
+
141
+ ```elm
142
+ module Main exposing (..)
143
+
144
+ import Html exposing (Html, programWithFlags, h1, text)
145
+ import Html.Attributes exposing (style)
146
+
147
+
148
+ -- MODEL
149
+
150
+
151
+ type alias Flags =
152
+ { message : String
153
+ , name : String
154
+ }
155
+
156
+
157
+ type alias Model =
158
+ { message : String
159
+ , name : String
160
+ }
161
+
162
+
163
+ type Msg
164
+ = NoOp
165
+
166
+
167
+
168
+ -- INIT
169
+
170
+
171
+ init : Flags -> ( Model, Cmd Msg )
172
+ init flags =
173
+ let
174
+ { message, name } =
175
+ flags
176
+ in
177
+ ( Model message name, Cmd.none )
178
+
179
+
180
+
181
+ -- UPDATE
182
+
183
+
184
+ update : Msg -> Model -> ( Model, Cmd Msg )
185
+ update msg model =
186
+ case msg of
187
+ NoOp ->
188
+ ( model, Cmd.none )
189
+
190
+
191
+
192
+ -- SUBSCRIPTIONS
193
+
194
+
195
+ subscriptions : Model -> Sub Msg
196
+ subscriptions model =
197
+ Sub.none
198
+
199
+
200
+
201
+ -- VIEW
202
+
203
+
204
+ view : Model -> Html Msg
205
+ view model =
206
+ h1 [ style [ ( "display", "flex" ), ( "justify-content", "center" ) ] ]
207
+ [ text (model.message ++ ", " ++ model.name ++ "!") ]
208
+
209
+
210
+
211
+ -- MAIN
212
+
213
+
214
+ main : Program Flags Model Msg
215
+ main =
216
+ programWithFlags
217
+ { view = view
218
+ , init = init
219
+ , update = update
220
+ , subscriptions = subscriptions
221
+ }
222
+
223
+ ```