Rails 6.0 详细介绍全面切换 assets pipeline 到 webpacker
rails
本文首发于 RubyChina,这里是我私人博客,如需讨论,建议移步 RubyChina 对应帖子,帖子地址
开篇说明:本文力争成为介绍和开始使用 webpacker 最好用的中文入门文档,欢迎各位提出改进建议。
Rails 6 默认启用了 webpacker 作为 Javascript 文件的管理方案,但使用起来与 assets pipeline 颇有不同,但 webpacker 的优点非常明显,所以强烈建议各位 Railser 切换,故此这里详细介绍。
在文尾,我们 dao42 团队准备了开箱即用的初始化新项目方案,有兴趣动手的朋友可以研究一番。
webpacker 的好处
- webpacker 编译很快,可以让你节省大量开发成本。
- webpacker 是目前前端界标准事实的打包工具,从此引用 JS 库不用找 gem 包了。
- webpacker 让你写 JS 更规范,可以直接用 ES6。
webpacker 的安装
Rails 6.0 默认已经安装了 webpacker,但同时也安装了 assets pipeline( sprockets ),两者混合使用差异较大,我推荐完全移除 assets pipeline:
新项目
$ rails new my_app --webpack --skip-sprockets
旧项目,将 config/application.rb
的 `require 'rails/all' 替换为:
require "rails"
%w(
active_record/railtie
active_storage/engine
action_controller/railtie
action_view/railtie
action_mailer/railtie
active_job/railtie
action_cable/engine
action_mailbox/engine
action_text/engine
rails/test_unit/railtie
#sprockets/railtie
).each do |railtie|
begin
require railtie
rescue LoadError
end
end
第二步,删除 app/assets
目录,在 app/javascript
目录分别创建 styles/
, fonts/
, js
, images
目录。
第三步,解掉 app/javascript/packs/application.js 中的 images 打包注释:
const images = require.context('../images', true)
const imagePath = (name) => images(name, true)
第四步,将 app/views/layouts/application.html.erb
中的 stylesheet_include_tag
替换为 stylesheet_pack_tag
。
最后,在开发时不要忘了启动 bin/webpack-dev-server
,这个工具可以实时编译资源,并帮你刷新浏览器。
webpacker 下如何写我们的 JS 与 CSS
上述安装配置后,我们彻底移除了 assets pipeline,现在我们的目录布局如下:
app/javascript/packs/
: 放在这里面的 js 文件.,最终会打包出来供 javascript_pack_tag
引用。
app/javascript/js/
: 在这里写我们自己的 JS 逻辑。
app/javascript/styles/
: 在这里写我们自己的 CSS 逻辑。推荐直接写 SCSS。
app/javascript/images/
: 放项目用到的图片资源。fonts/
目录类同。
思维调整
我们从思维上要发生一个根本变化,即:一切皆 JS
。所以我们的 CSS 也需要在 application.js 中引入:
import 'styles/application'
模块隔离
webpacker 会将各文件中的对象都隔离,所以无须担心互相影响,也没有所谓的全局变量。所以写一个组件也变得很简单:
// app/javascript/js/a.js
var a = 1
export default a
// app/javascript/js/b.js
import a from './a'
console.log(a)
引入前端库
引入前端库变的简单了:
先用 yarn 安装一下
$ yarn add bootstrap
然后在 app/javascript/packs/application.js
中引用
import 'bootstrap/dist/js/bootstrap'
CSS 中是这样的,app/javascript/styles/application.scss
引用
@import 'bootstrap/scss/bootstrap';
以上路径可以直接去相关前端库的安装说明中找即可。
注意: 引用相对路径时一定要加上 ./
,否则不生效并且不一定报错。
JS 调试
webpacker 默认已经将 map 文件装载,所以调试起来仍然相当方便。见下图
同时,也可以用 debugger
指令来强制下断点。
View 中引用资源的方法
stylesheet_link_tag
与 javascript_include_tag
均已废弃不再使用。
现在常用的几个
1.stylesheet_pack_tag
: 加载 CSS 资源
用法:
stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
2.javascript_pack_tag
: 加载 JS 资源
用法
javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
3.asset_pack_path
: 类似于 asset_path
,加载图片、字体等资源
用法( 注意 media/images 这个路径,要加上 media 这个前缀,而且不能使用相对路径 )
asset_pack_path('media/images/favicon.ico')
4.image_pack_tag
: 取代image_tag
,更明确的加载图片
用法
image_pack_tag 'media/images/calendar.png'
或( 两者等价 )
image_pack_tag 'calendar.png'
webpacker 的原理简单说明
webpacker 是包装自 webpack 并且基本做到零配置开箱即用。配置文件在 config/webpacker.yml,无须做任何调整。
webpack 分为 Entry, Output, Loaders, Plugins 几个关键概念。最新的大版本是 v4。
webpack 会将所有的资源都进行依赖分析,生成依赖树,并最终打成一个或多个包。
示例: 常用库的安装
jQuery
$ yarn add jquery@3.3.1
添加一个 webpack 插件,确保 $, jQuery, 'window.jQuery' 可以在JS库中使用。
// config/webpack/environment.js
const webpack = require('webpack')
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
)
开始使用
// app/javascript/packs/application.js
import 'jquery'
Bootstrap
$ yarn add bootstrap@4.3.1 popper.js
在 app/javascript/styles/ 中创建 bootstrap_custom.scss
// app/javascript/styles/bootstrap_custom.scss
@import 'bootstrap/scss/bootstrap';
// app/javascript/styles/application.scss
@import 'bootstrap_custom'
最后,引用 JS:
// app/javascript/packs/application.js
import 'bootstrap/dist/js/bootstrap'
rails-template
是不是仍然感觉有点复杂,没关系, dao42/rails-template
已经为你的新项目初始化做好了开箱即用。
dao42/rails-template
已经经历过 2 年半的持续升级维护,做好了新项目很多方面的开箱即用。
dao42/rails-template
全面拥抱 webpacker。dao42/rails-template
集成最新的bootstrap4
,font-awesome5
,无须额外任何配置。dao42/rails-template
集成 mina 发布套件,一键发布项目。
点击这里开始体验 webpacker 的便利之处:dao42/rails-template。
参考文稿
发表于 2019.07.11
© 自由转载 - 非商用 - 非衍生 - 保持署名
wotogo • 2021-01-20 11:42
找了好久才找到你这篇文章,照着做后,启动 puma 报错:
Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
But did not, please create this file and use it to link any assets that need
to be rendered by your app:
Example:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
and restart your server