この記事の各Version
- Rails 5.2.0
- Ruby 2.5.0
- node 9.11.2
- yarn 1.7.0
- laravel-mix ^2.0
What・Why?
Laravel Mixとは?
- https://github.com/JeffreyWay/laravel-mix
- LaravelのAssets Compileの機能
- webpackのWrapper API
- Node.js のライブラリ、PHPを必要としない
なぜ Laravel Mixなのか?
- RailsのSprockets、AssetsPipelineを使いたくない
- Too fu*kin' outdated
- webpacker使いたくない
- RubyのRuntimeで動いてるのがダサい
- 設定がなぞ
- ディレクトリがなぞ
- .js.erb とかやりがち
- 結局フロントエンドエンジニアに迷惑かける
なぜwebpackを直接使わないのか?
- webpackを使って開発はじめるまでに設定ファイルをたくさん書くのが大変
- シュッと環境整備してES6やTypeScript使いたい
- 15分でes6書きたい
導入編
Laravel Mixを設定する
Laravel Mixに必要ファイルをLaravelのリポジトリからコピーする
- webpack.mix.js
- package.json
- resources
- assets
- js
- components
- ExampleComponent.Vue
- app.js
- bootstra.js
- sass
publicPathを設定する
webpack.mix.js
let mix = require('laravel-mix');
+ mix.setPublicPath('public').
+ js('resources/assets/js/app.js', 'public/js')
- mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
publicPathを設定することで、mix-manifest.json
がpublicフォルダに吐き出されるようになる。こちらの方が都合がいいので変更する。
.gitignoreにLaravel Mixの設定を追加する
.gitignore
+ public/css/app.css
+ public/js/app.js
+ public/js/manifest.js
+ public/js/vendor.js
+ public/mix-manifest.json
を追記する。
npm, yarnのインストール(macOS ver)
$ brew install nodejs
$ npm install -g yarn
docker環境の場合こちらを参考にしてください
node_modules のインストール
$ yarn install
Assets compile(development)
$yarn run dev
public/mix-manifest.json
{
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css"
}
production用にversioningする
# webpack.mix.js
let mix = require('laravel-mix');
mix.setPublicPath('public')
.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
+ # productionの時はversioningする
+ if (mix.inProduction()) {
+ mix.version();
+ }
Assets Compile(production)
$ yarn run prod
public/mix-manifest.json
{
"/js/app.js": "/js/app.js?id=c1d308b8f13f8ce146b7",
"/css/app.css": "/css/app.css?id=943ad87b58616383f50a"
}
minifyされてる
Rails側での対応
LaravelMixによってpublicフォルダーにコンパイルされたcssとjsが吐き出される。またmix-manifest.json
にファイルのハッシュ値が記録されているので、RailsのView側でハッシュを利用したURLを生成するヘルパーを用意する。
ヘルパーを用意する
app/helpers/laravel_mix_helper
module LaravelMixHelper
class LaravelMixError < StandardError; end
MANIFEST_FILE = 'public/mix-manifest.json'
def mix(path)
unless File.exists?(MANIFEST_FILE)
raise LaravelMixError.new('The Mix manifest does not exist. Run `yarn run dev`.')
end
manifest = JSON.parse(File.read(MANIFEST_FILE))
asset_path(manifest[path])
end
end
app/views/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
+ <link rel="stylesheet" href="<%= mix('/css/app.css') %>">
+
+ <script src="<%= mix('/js/app.js') %>"></script>
</head>
<body>
<%= yield %>
</body>
</html>
templateにVue Componentを追記してみる
+ <div id="app">
+ <example-component />
+ </div>
表示させてみる
Laravel Mixのデフォルトで用意されたES6で書かれたVue.jsのコンポーネントを表示することが出来ました。versioningも正しく出来てます。
Laravel MixのAPI
https://github.com/JeffreyWay/laravel-mix/blob/master/setup/webpack.mix.js
// Full API
// mix.js(src, output);
// mix.react(src, output); <-- Identical to mix.js(), but registers React Babel compilation.
// mix.preact(src, output); <-- Identical to mix.js(), but registers Preact compilation.
// mix.coffee(src, output); <-- Identical to mix.js(), but registers CoffeeScript compilation.
// mix.ts(src, output); <-- TypeScript support. Requires tsconfig.json to exist in the same folder as webpack.mix.js
// mix.extract(vendorLibs);
// mix.sass(src, output);
// mix.standaloneSass('src', output); <-- Faster, but isolated from Webpack.
// mix.fastSass('src', output); <-- Alias for mix.standaloneSass().
// mix.less(src, output);
// mix.stylus(src, output);
// mix.postCss(src, output, [require('postcss-some-plugin')()]);
// mix.browserSync('my-site.test');
// mix.combine(files, destination);
// mix.babel(files, destination); <-- Identical to mix.combine(), but also includes Babel compilation.
// mix.copy(from, to);
// mix.copyDirectory(fromDir, toDir);
// mix.minify(file);
// mix.sourceMaps(); // Enable sourcemaps
// mix.version(); // Enable versioning.
// mix.disableNotifications();
// mix.setPublicPath('path/to/public');
// mix.setResourceRoot('prefix/for/resource/locators');
// mix.autoload({}); <-- Will be passed to Webpack's ProvidePlugin.
// mix.webpackConfig({}); <-- Override webpack.config.js, without editing the file directly.
// mix.babelConfig({}); <-- Merge extra Babel configuration (plugins, etc.) with Mix's default.
// mix.then(function () {}) <-- Will be triggered each time Webpack finishes building.
// mix.extend(name, handler) <-- Extend Mix's API with your own components.
// mix.options({
// extractVueStyles: false, // Extract .vue component styling to file, rather than inline.
// globalVueStyles: file, // Variables file to be imported in every component.
// processCssUrls: true, // Process/optimize relative stylesheet url()'s. Set to false, if you don't want them touched.
// purifyCss: false, // Remove unused CSS selectors.
// uglify: {}, // Uglify-specific options. https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
// postCss: [] // Post-CSS options: https://github.com/postcss/postcss/blob/master/docs/plugins.md
// });
React, TypeScript, PostCSS, Stylus どれも速攻で環境つくれます。
まとめ
Laravel Mixを使ってRailsでも簡単に最新のフロントエンド環境構築してみてはいかがでしょうか??