ãã®è¨äºã§ã¯ãWebpacker
ã使ã£ã¦ãã Rails ã¢ããªããWebpacker
ãå¥ãããwebpack
ã使ãããã«ããããã®æé ãæ¸ãã¦ããã
Webpacker
ãæ¢ãããçç±ã¯æ§ã
ã ãã主ãªçç±ã¯ä»¥ä¸ã®ãããªæãã ãããã
- ç¾æç¹ã§ã¯
Webpacker
ã使ç¨ãã¦ããwebpack
ã®ãã¼ã¸ã§ã³ã¯3.x
ã§ãææ°ãã¼ã¸ã§ã³ã«è¿½å¾ã§ãã¦ããªã webpack
ã®è¨å®ã®ä»ã«ããWebpacker
ã®è¨å®ãã«ã¤ãã¦å¦ã°ãªããã°ãªãããç¡é§ãå¤ãwebpack
ãç´æ¥è§¦ãã°æ¸ã話ãã常ã«Webpacker
ã¨ãã仲ä»è ãéãã¦ä½æ¥ããªããã°ãªããªã- ã«ã¹ã¿ãã¤ãºããã¤ã°ã¬ã¼ã·ã§ã³ã®éã«ãèæ ®ããªããã°ãªããªãè¦ç´ ãå¢ãã¦ãã¾ã
æ軽ã«ããã³ãã¨ã³ãéçºç°å¢ãå°å
¥ã§ãããã¨ããã®ãWebpacker
ã®å©ç¹ã§ãããã«ã¹ã¿ãã¤ãºããã¢ãããã¼ããããå¿
è¦ã«ãªã£ã¦ãã¾ãã®ãªããã¾ãã¡ãªããã¯ãªããã¨å人çã«ã¯æãã¦ããã
ååã®è¨äºã§ãWebpacker
㨠Vue ã使ã£ããµã³ãã«ã¢ããªãä½æããã
ãã®ã¢ããªããWebpacker
ãåé¤ããwebpack
㧠Vue ã³ã³ãã¼ãã³ããªã©ããã«ãã§ããããã«ãã¦ããã
ãã®è¨äºã®ã´ã¼ã«ã¯ãã¡ããã¨åãããã«ããããã®ä»çµã¿ãä½ãããã¨ã§ãã£ã¦ãWebpacker
ãè¡ã£ã¦ãããã¨ãå¿ å®ã«åç¾ãããã¨ã¯ããªãã
Webpacker
ãå¥ããããã«å¿
è¦ãªä½æ¥ã®å
¨ä½åãæ´ã¿ããããè¨é²ãã¦ãããã¨ããã®è¨äºã®æå³ã§ãããç´°é¨ã«ã¯è¸ã¿è¾¼ã¾ãªãã
ãã ãã¹ã¿ã¤ã«ã·ã¼ããå¥ãã¡ã¤ã«ã¨ãã¦æ½åºãããªã©ã®åºæ¬çãªåä½ã¯è¸è¥²ããã
Webpacker
ãæããã¦ãã主ãªä»äºã¯ä»¥ä¸ã
app/javascript/packs
ã«å ¥ã£ã¦ãããã¡ã¤ã«ãã¨ã³ããªãã¡ã¤ã«ã¨ãã¦ãpublic/packs
ã«ãã¤ã¸ã§ã¹ãä»ãã§ãã«ããã- ãããã§ã¹ããã¡ã¤ã«ã¨ãã¦
pubplic/packs/manifest.json
ãçæãã webpack-dev-server
ã使ããã¨ã§ãå·®åãæ¤ç¥ããèªåçã«ãã«ãããã©ã¦ã¶ã®ãªãã¼ããè¡ãjavascript_pack_tag
ãstylesheet_pack_tag
ã§ããã«ãããããã¡ã¤ã«ãèªã¿è¾¼ãã
ãããwebpack
ã§å®ç¾ããã
以ä¸ã®ãã¼ã¸ã§ã³ã§ä½æ¥ãã¦ããã
- Ruby 2.5.3
- Ruby on Rails 5.2.2
- webpack 4.28.3
Step1 Webpacker ã®åé¤
ã¾ãã¯ãWebpacker
ãåé¤ãã¦ããã
Gemfile
ããgem 'webpacker'
ãåé¤ãã¦ã$ bundle
ãå®è¡ã
$ yarn remove @rails/webpacker
ãå®è¡ã
ããã§ã©ã¤ãã©ãªãåé¤ã§ããããé¢é£ãã¡ã¤ã«ã¯ã¾ã ã¾ã æ®ã£ã¦ããã®ã§ããããåé¤ãã¦ããã
- bin/webpack
- bin/webpack-dev-server
- config/webpack/development.js
- config/webpack/environment.js
- config/webpack/loaders/vue.js
- config/webpack/production.js
- config/webpack/test.js
- config/webpacker.yml
æå¾ã«ãè¨å®ãã¡ã¤ã«ããWebpacker
ã«é¢ããè¨è¿°ãåé¤ããã
diff --git a/config/environments/development.rb b/config/environments/development.rb index 4b8cc17..1311e3e 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,6 +1,4 @@ Rails.application.configure do - # Verifies that versions and hashed value of the package contents in the project's package.json - config.webpacker.check_yarn_integrity = true # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on diff --git a/config/environments/production.rb b/config/environments/production.rb index 457946a..b4dbe4a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,6 +1,4 @@ Rails.application.configure do - # Verifies that versions and hashed value of the package contents in the project's package.json - config.webpacker.check_yarn_integrity = false # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests.
ã¾ããTurbolinks
ãæå¹ã«ãªã£ã¦ããå ´åã¯å¿ããã«ç¡å¹åãã¦ããã
ãããæå¹ã«ãªã£ã¦ããã¨ããã¼ã¸é·ç§»æã«ä¸æãåããªããªãã
Turbolinks
ã¨å
±åãããæ¹æ³ãããã¨æãããããã§ã¯æ±ããªãã
Step2 webpack ã§ãã«ãã§ããããã«ãã
ãã®æç¹ã§ã¯ Rails ã¨ã®é£æºã¯èãããã¾ãã¯app/javascript/packs
ã«å
¥ã£ã¦ãããã¡ã¤ã«ããã«ãã§ããããã«ããã
å¿ è¦ãªã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ããã
$ yarn add -D webpack webpack-cli $ yarn add -D css-loader file-loader sass-loader node-sass mini-css-extract-plugin vue-loader@latest $ yarn add -D webpack-manifest-plugin
webpack@4
ããã¯ãCSSã®æ½åºã«ã¯extract-text-webpack-plugin
ã§ã¯ãªãmini-css-extract-plugin
ã使ããã¨ãæ¨å¥¨ããã¦ããã
ããããWebpacker
çµç±ã§ Vue ã®éçºç°å¢ãæ´ããå ´åã¯vue-loader
ã®v14
ãå
¥ã£ã¦ããããããmini-css-extract-plugin
ã«å¯¾å¿ãã¦ããªãããã®ãããææ°ãã¼ã¸ã§ã³ã®vue-loader
ãå
¥ããå¿
è¦ãããã
次ã«ãããã¸ã§ã¯ãã®ã«ã¼ããã£ã¬ã¯ããªç´ä¸ã«webpack.config.js
ãç¨æããã
ãã£ã¨ããæ¸ãæ¹ãããã¨ã¯æãããããã¸ã§ã¯ãã«ãã£ã¦ã¯ããã§ã¯ãã¡ãããããªãããä»åæ±ã£ã¦ãããµã³ãã«ã¢ããªã®å ´åã¯ããã§åé¡ãªãåãã
Babel ã®å¯¾å¿ã¯æ¬¡ã® Step ã§è¡ãã
const path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = (env, argv) => { const isProduction = argv.mode === 'production'; return { context: path.resolve(__dirname, 'app/javascript/packs'), entry: { application: './application.js', 'application-stylesheet': './application.sass', hello_vue: './hello_vue.js', }, output: { path: path.resolve(__dirname, 'public/packs'), filename: isProduction ? '[name]-[contentHash].js' : '[name]-[hash].js', }, module: { rules: [ {test: /\.(css|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']}, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: { outputPath: 'images/', name: '[name]-[hash].[ext]', }, }, ], }, { test: /\.vue$/, exclude: /node_modules/, loader: 'vue-loader', options: { extractCSS: true, }, }, ], }, plugins: [ new VueLoaderPlugin(), new ManifestPlugin(), new MiniCssExtractPlugin({filename: '[name]-[contentHash].css'}), ], }; }
ãã¨ã¯ãnpm ã¹ã¯ãªããã¨ãã¦"build": "yarn && webpack --mode=production"
ãç»é²ãã$ yarn build
ãå®è¡ããã°ãpublic/packs
ã«ãã«ããããã
Step3 Babel ã®å¯¾å¿ã¨ v7 ã¸ã®ãã¤ã°ã¬ã¼ã·ã§ã³
Rails5.2
ã®Webpacker
ç°å¢ã§ä½¿ããã Babel ã¯v6
ãªã®ã§ããã®æ©ä¼ã«v7
ã«ä¸ãã¦ããã
å¿ è¦ãªã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ã
$ yarn add -D babel-loader @babel/core @babel/preset-env @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties
次ã«ããã¤ã°ã¬ã¼ã·ã§ã³ãè¡ãããå ¬å¼ã®ãã¼ã«ã便å©ãªã®ã§ããã使ãã
ãã®ãã¼ã«ã使ããã¨ã§ãå¿ è¦ãªã©ã¤ãã©ãªã®ã¤ã³ã¹ãã¼ã«ãªã©ãè¡ãããã
$ npm i -g babel-upgrade $ babel-upgrade --write --install
.babelrc
ã®æ´æ°ãèªåçã«è¡ããããã¯ããªã®ã ããç°å¢ã«ãã£ã¦ã¯å®è¡ãããªãã£ãã
åãæ¢ããä»åã®ã±ã¼ã¹ã§ã¯ä»¥ä¸ã®ããã«ããã°ããã
diff --git a/.babelrc b/.babelrc index 47cfe92..3233cc0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,24 +1,31 @@ { "presets": [ - ["env", { - "modules": false, - "targets": { - "browsers": "> 1%", - "uglify": true - }, - "useBuiltIns": true - }] + [ + "@babel/preset-env", + { + "modules": false, + "targets": { + "browsers": "> 1%" + } + } + ] ], - "plugins": [ - "syntax-dynamic-import", - "transform-object-rest-spread", - ["transform-class-properties", { "spec": true }] + "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-proposal-object-rest-spread", + [ + "@babel/plugin-proposal-class-properties", + { + "spec": true + } + ] ], - "env": { "test": { - "presets": ["env", "power-assert"] + "presets": [ + "@babel/preset-env", + "power-assert" + ] } } }
ãã¨ã¯webpack
ã§babel-loader
ã使ãããã«ããã°ããã
diff --git a/webpack.config.js b/webpack.config.js index 89d3790..2fcb99d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -19,6 +19,11 @@ module.exports = (env, argv) => { }, module: { rules: [ + { + test: /\.js$/, + include: path.resolve(__dirname, 'app'), + use: 'babel-loader', + }, {test: /\.(css|sass)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']}, { test: /\.(png|jpg|gif)$/,
ããã§ããã«ãã®éã« Babel ã«ãããã©ã³ã¹ãã¤ã«ãè¡ãããããã«ãªãã
Babel ã®ãã¼ã¸ã§ã³ãv7
ã«ä¸ãããã¨ã§ãbabel-preset-power-assert
ã®ææ°ãã¼ã¸ã§ã³ï¼v3
ï¼ã使ããããã«ãªã£ãã®ã§ã対å¿ãã¦ããã
$ yarn add -D [email protected]
Step4 webpack-dev-server ãå°å ¥
ãã«ãã¯åºæ¥ãããã«ãªã£ãã®ã§ã次ã¯ãwebpack-dev-server
ã使ããããã«ãããããããªãã¨èªåãã«ããèªåãªãã¼ããåºæ¥ãªãã®ã§ãéçºã«æ¯éããããã¦ãã¾ãã
Webpacker
ãã¤ã³ã¹ãã¼ã«ããã¨ãã«å°å
¥ãããwebpack-dev-server
ã¯ãã¼ã¸ã§ã³ãå¤ãã®ã§ãæ´æ°ããã
$ yarn add -D webpack-dev-server@latest
ã³ãã³ãã®è¿½å ã¨è¨å®ãã¡ã¤ã«ã¸ã®è¿½è¨ãè¡ãã
diff --git a/package.json b/package.json index 98cde84..b573325 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "webpacker-example", "private": true, "scripts": { + "start": "yarn && webpack-dev-server --mode=development", "build": "yarn && webpack --mode=production", "test": "jest" }, diff --git a/webpack.config.js b/webpack.config.js index 2fcb99d..4e94f0b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -52,5 +52,16 @@ module.exports = (env, argv) => { new ManifestPlugin(), new MiniCssExtractPlugin({filename: '[name]-[contentHash].css'}), ], + devServer: { + publicPath: '/packs/', + historyApiFallback: true, + port: 3035, + }, }; }
$ yarn start
ãå®è¡ããhttp://localhost:3035/packs/manifest.json
ã«ã¢ã¯ã»ã¹ã§ããã°æåã§ããã
Step5 ãã«ãã¼ã¿ã°ã®å®è£
次ã¯ãããããRails ã¨ã®ã¤ãªãè¾¼ã¿ãè¡ãã
javascript_pack_tag
ã«ä»£ãããã«ãã¼ã¿ã°ãä½æããã
app/helpers/webpack_bundle_helper.rb
ã¨ãã¦ã以ä¸ã®ãã¡ã¤ã«ãä½æããã
require 'open-uri' # webpackã«ãããã«ããã¡ã¤ã«èªã¿è¾¼ã¿ç¨ãã«ãã¼ module WebpackBundleHelper class BundleNotFound < StandardError; end def javascript_bundle_tag(entry, **options) path = asset_bundle_path("#{entry}.js") options = { src: path, defer: true }.merge(options) # async 㨠defer ã両æ¹æå®ããå ´åããµã¤ã㯠async ãåªå ããããã # defer ãã対å¿ãã¦ãªãå¤ããã©ã¦ã¶ã®æåãèããã®ãé¢åãªã®ã§ã両æ¹æå®ã¯é²ãã§ãã options.delete(:defer) if options[:async] javascript_include_tag '', **options end def stylesheet_bundle_tag(entry, **options) path = asset_bundle_path("#{entry}.css") options = { href: path }.merge(options) stylesheet_link_tag '', **options end private # ã¢ã»ãããç½®ããã¦ãããµã¼ãã¼ãè¿ã def asset_server port = Rails.env === 'production' ? '3000' : '3035' "http://#{request.host}:#{port}/" end def pro_manifest File.read('public/packs/manifest.json') end def dev_manifest # webpack-dev-serverããç´æ¥åå¾ãã OpenURI.open_uri("#{asset_server}packs/manifest.json").read end def test_manifest File.read('public/packs-test/manifest.json') end def manifest return @manifest ||= JSON.parse(pro_manifest) if Rails.env.production? return @manifest ||= JSON.parse(dev_manifest) if Rails.env.development? return @manifest ||= JSON.parse(test_manifest) end def valid_entry?(entry) return true if manifest.key?(entry) raise BundleNotFound, "Could not find bundle with name #{entry}" end def asset_bundle_path(entry, **options) valid_entry?(entry) asset_path("#{asset_server}packs/" + manifest.fetch(entry), **options) end end
ããã¦ãããããã³ãã¬ã¼ããã¡ã¤ã«ã®ãªãã§ä½¿ãã
diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb index 3bfde83..a418880 100644 --- a/app/views/posts/index.html.erb +++ b/app/views/posts/index.html.erb @@ -26,7 +26,7 @@ <%= link_to 'New Post', new_post_path %> -<%= javascript_pack_tag 'application' %> -<%= stylesheet_pack_tag 'application' %> -<%= javascript_pack_tag 'hello_vue' %> -<%= stylesheet_pack_tag 'hello_vue' %> +<%= javascript_bundle_tag 'application' %> +<%= stylesheet_bundle_tag 'application-stylesheet' %> +<%= javascript_bundle_tag 'hello_vue' %> +<%= stylesheet_bundle_tag 'hello_vue' %>
$ bin/rails s
ã¨$ yarn start
ãåæã«ä½¿ã£ã¦ãhttp://localhost:3000/
ã«ã¢ã¯ã»ã¹ãã¦ã¿ãã
ãããã¯ã·ã§ã³ç°å¢ã確èªãããå ´åã¯ã$ yarn build
ããããã§$ bin/rails s -e production
ãå®è¡ããã
æ¦ãåãã¦ããããapp/javascript/app.vue
ã®ãªãã§ä½¿ã£ã¦ããç»åã表示ããã¦ããªãã
æå¾ã®ä»ä¸ãã¨ãã¦ããã®åé¡ãä¿®æ£ããã
Step6 Vueã®ã³ã³ãã¼ãã³ãã§ä½¿ã£ã¦ããç»åã表示ã§ããããã«ãã
表示ããã¦ããªãç»åã ãã確èªãã¦ã¿ãã¨ãhttp://localhost:3000/images/usa-xxxxx.png
ãåç
§ãã¦ããã
ã ããã®ãã¹ã¯èª¤ãã§ããã以ä¸ã®ãã¹ãæ£ããã
ç°å¢ | ãã¹ |
---|---|
ãããããã¡ã³ã | http://localhost:3035/packs/images/usa-xxxxx.png |
ãããã¯ã·ã§ã³ | http://localhost:3000/packs/images/usa-xxxxx.png |
ãã®åé¡ã¯ãããã·ãä½æãã¦å¯¾å¿ãããã¨ã«ããã
ã¾ããrack-proxy
ãã¤ã³ã¹ãã¼ã«ã
Gemfile
ã«gem 'rack-proxy'
ã¨è¿½è¨ãã¦ã$ bundle
ãå®è¡ããã°ããã
次ã«ãlib/tasks/assets_path_proxy.rb
ã¨ããååã§ãããã·ãä½æã
require 'rack/proxy' # Vue ã®ã³ã³ãã¼ãã³ãã®ãªãã§å©ç¨ãã¦ããç»åã«ã¢ã¯ã»ã¹ã§ããããã«ããããã®ãããã· class AssetsPathProxy < Rack::Proxy def perform_request(env) if env['PATH_INFO'].include?("/images/") if Rails.env != 'production' dev_server = env['HTTP_HOST'].gsub(':3000', ':3035') env['HTTP_HOST'] = dev_server env['HTTP_X_FORWARDED_HOST'] = dev_server env['HTTP_X_FORWARDED_SERVER'] = dev_server end env['PATH_INFO'] = "/packs/images/" + env['PATH_INFO'].split("/").last super else @app.call(env) end end end
ããã¦ãè¨å®ãã¡ã¤ã«ã«ãããã·ã使ãè¨å®ãæ¸ãè¾¼ãã
diff --git a/config/environments/development.rb b/config/environments/development.rb index 1311e3e..f4a4f26 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,3 +1,5 @@ +require_relative '../../lib/tasks/assets_path_proxy' + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -12,6 +14,8 @@ Rails.application.configure do # Show full error reports. config.consider_all_requests_local = true + config.middleware.use AssetsPathProxy, ssl_verify_none: true + # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. if Rails.root.join('tmp', 'caching-dev.txt').exist? diff --git a/config/environments/production.rb b/config/environments/production.rb index b4dbe4a..dc6fac5 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,3 +1,5 @@ +require_relative '../../lib/tasks/assets_path_proxy' + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -14,6 +16,8 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + config.middleware.use AssetsPathProxy, ssl_verify_none: true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true
ããã§ã表示ãããããã«ãªãã
2019/1/25 追è¨
webpack
+ Rails
ã®ã¦ã§ãã¢ããªãä½ã£ãã
numb86-tech.hatenablog.com