0. 引言
去年写过一篇『新建带 webpacker 的 Rails 项目』,当时还是 Rails 5,需要手动加入 webpacker,而现在 Rails 6 已经默认使用 webpacker 了。一年来笔者也在之前的文章里修修补补,现在想想还是重写一篇吧。
1. 新建 Gemfile:
source 'https://rubygems.org'
gem 'rails'
注:这里之所以不直接改写成 gems.ruby-china 的镜像,是因为需要用 –force 参数覆盖已有文件,即 Gemfile 的 source 会被重写回默认源。为了避免在国内出现非常慢以至于卡在 bundle install
的情况,我在制作 docker image 的时候就直接覆盖了 Gemfile 的 source:(或者直接 –skip-bundle)
RUN bundle config mirror.https://rubygems.org https://gems.ruby-china.com
2. 新建 docker-compose.yml
version: '3.7'
services:
web:
image: registry.cn-shanghai.aliyuncs.com/aaron_dev/rails-base-image:v2
command: bash -c "rm -f /app/tmp/pids/server.pid && rails s -p 5000 -b 0.0.0.0"
volumes:
# old string format
- templar-sync:/app:nocopy
# store gems locally to look into source code
- ./.gems:/usr/local/bundle
ports:
- 5000:5000
environment:
- WEBPACKER_DEV_SERVER_HOST=webpack_dev_server
# comment for future use
# depends_on:
# - db
# byebug, use attach
stdin_open: true
tty: true
webpack_dev_server:
image: registry.cn-shanghai.aliyuncs.com/aaron_dev/rails-base-image:v2
command: bin/webpack-dev-server
ports:
- 3035:3035
volumes:
- templar-sync:/app:nocopy
- ./.gems:/usr/local/bundle
environment:
- WEBPACKER_DEV_SERVER_HOST=0.0.0.0
db:
image: postgres
volumes:
# new format
- type: volume
source: dbdata
target: /var/lib/postgresql/data
volume:
nocopy: true
ports:
- 54321:5432
volumes:
dbdata:
templar-sync:
external: true
3. 新建 docker-sync.yml
version: '2'
syncs:
templar-sync:
src: './'
注:需要在本地 gem install docker-sync 安装 docker-sync,参考另一篇『用 docker-sync 在 Mac 进行文件系统同步』。
4. 在项目目录下运行:
docker-compose run --rm web gem install bundler
docker-sync start
docker-compose run --rm web bundle install
docker-compose run --rm web rails new [app-name] --force --database=postgresql --skip-bundle --webpack=react
--skip-sprockets --skip-turbolinks
参数可选,webpack 允许将 css 依旧交给 sprockets 管理;turbolinks 除非特殊需求,否则不建议关闭
注:这里补充一个知识点,在服务器上安装 docker 后,因为一般我们不会用超级用户,所以是没有权限直接运行 docker 命令的,如果不想所有命令前都加上 sudo 的话,就要把你的用户加到 docker 组里,运行如下命令然后重新登录即可:
sudo usermod -aG docker [server_username]
然后检查 /etc/group 的 docker 组知否已经加入了用户: docker:x:999:[username]
5. 修改 database.yml 如下:
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password:
6. 项目初始化完成后,修改 views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_pack_tag 'application' %>
</head>
<body>
<%= yield %>
<!-- 加载完页面再 load js -->
<%= javascript_pack_tag 'application' %>
</body>
</html>
7. 启动项目
docker-compose up
docker-compose exec web rails db:create
docker-compose exec web rails db:migrate
至此,我们就快速建立了一个基于 webpack 的 Rails 项目,然后加入一些基础的前端依赖,并进一步完善 webpack 的基础配置。
进入 web 容器 docker-compose exec -it web bash
,运行:
yarn add bootstrap
yarn add popper.js
yarn add jquery
yarn add @fortawesome/fontawesome-free
然后修改 config/webpack/environment.js 如下:
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
/**
* Automatically load modules instead of having to import or require them everywhere.
* Support by webpack. To get more information:
*
* https://webpack.js.org/plugins/provide-plugin/
* http://j.mp/2JzG1Dm
*
* 配置文件,更改需要重启服务
*/
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
)
module.exports = environment
这个文件可以参考这两篇文章:https://joey.io/how-to-use-jquery-in-rails-5-2-using-webpack/, https://webpack.js.org/plugins/provide-plugin/
再引入这些第三方组件 app/javascript/packs/application.js
:
// 第三方库加载
import "bootstrap"
import "bootstrap/dist/css/bootstrap.min.css"
import "@fortawesome/fontawesome-free/css/all.min.css"
8. 允许 webpack 打包 css 文件
webpacker 4 之后,默认只会打包 js,若要启用 css 打包,需修改 config/webpacker.yml:
# Extract and emit a css file
extract_css: true
注:因为 webpack 将所有资源都打包成 JS 的方式伺服前端,所以如果不加这条,则 css 也会随着 JS 一起加载,结果就是 html 页面显示的时候 css 还未被加载,等到 JS 加载的时候 css 才渲染,所以每次在页面刷新的时候样式会从无到有地闪动一下