webpacker-jets 3.2.100

Sign up to get free protection for your applications and to get access to all the features.
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
+ ```