# 资产打包
理解Frappe框架中静态资产打包的工作方式的指南。
Frappe提供了一个在/app上可用的丰富的管理界面,这是一个用现代JavaScript语法编写的单页应用程序(SPA),样式是用SASS (.scss)文件编写的。这些文件浏览器无法直接理解,因此需要在发送到浏览器解析和执行之前进行编译。
Frappe自带了一个资产打包器,可以编译客户端资产,如:
.js(带有import和export的现代语法).ts(TypeScript文件).vue(Vue单文件组件).css(使用PostCSS处理的CSS).scss(SASS文件).sass(使用缩进语法的SASS文件).styl(Stylus文件).less(Less文件)
这些文件根据类型编译为.js或.css,并发送到浏览器。
# 构建资产
要使用资产打包器编译资产,您需要从frappe-bench文件夹运行以下命令:
$ bench build
您也可以通过提供--apps选项仅运行特定应用程序。
# 仅构建frappe资产
$ bench build --apps frappe
# 仅构建frappe和erpnext资产
$ bench build --apps frappe,erpnext
2
3
4
5
# 监视模式
当您使用打包文件时,您需要构建命令在您每次更改源文件时都运行。资产打包器提供了一个监视模式,它会监听文件系统的变化,并在文件变化时重新构建。
运行以下命令将启动一个长时间运行的过程,它监视您的文件并在它们变化时重新构建。每次重新构建时,它会记录一行包含文本"Compiled changes..."的日志。
$ bench watch
监视更改...
下午1:17:28:编译更改...
2
3
4
您也可以通过提供--apps选项仅运行特定应用程序。
# 仅监视erpnext资产
$ bench watch --apps erpnext
2
从版本14开始,如果资产在监视模式下重新构建,Desk将自动重新加载。此行为可以通过设置LIVE_RELOAD环境变量或更改common_site_config.json中的live_reload值来切换。
# 打包文件
打包文件是资产的入口点,打包器会抓取它进行编译。例如,如果在应用程序的public文件夹中有一个名为main.bundle.js的文件,它将被打包器自动抓取,并编译到/assets/[app]/dist/js/main.bundle.[hash].js。从输出内容计算出的唯一哈希也附加到文件名中,这对于浏览器中的缓存破坏非常有用。
类似地,如果在public文件夹中有一个名为style.bundle.scss的文件,它将被编译到/assets/[app]/dist/css/style.bundle.css。注意,扩展名从.scss变为.css,因为浏览器可以理解CSS文件,但不能理解SASS文件。打包文件可以存在于public文件夹的任何嵌套级别中,但它们总是被编译到dist/js或dist/css中,具体取决于它们的类型。这意味着如果在public/main.bundle.js有一个文件,而在public/src/main.bundle.js有另一个文件,那么后者的编译输出将覆盖前者。打包器还会为此类冲突打印警告。
一些打包输入和输出的示例:
| 输入 | 输出 |
|---|---|
[app]/public/main.bundle.js | /assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/src/main.bundle.js | /assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/src/utils/utils.bundle.js | /assets/dist/[app]/js/utils.bundle.[hash].js |
[app]/public/main.bundle.ts | /assets/dist/[app]/js/main.bundle.[hash].js |
[app]/public/main.bundle.css | /assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/styles/main.bundle.css | /assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.scss | /assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.sass | /assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.styl | /assets/dist/[app]/css/main.bundle.[hash].css |
[app]/public/main.bundle.less | /assets/dist/[app]/css/main.bundle.[hash].css |
# 从npm导入库
如果您熟悉现代Web开发,您可能需要从npm安装第三方库并在您的项目中使用它。
假设您想在应用程序中使用dayjs库来处理日期和时间。首先使用yarn通过运行以下命令从应用程序文件夹的根目录安装它。
$ cd frappe-bench/apps/myapp
$ yarn add dayjs
2
现在,您可以在您的源文件中这样导入它:
myapp/public/main.bundle.js
import * as dayjs from 'dayjs';
console.log(dayjs())
2
3
# 在HTML中包含打包资产
当打包文件被编译时,输出文件包含一个唯一的哈希。因此,您不能硬编码文件的路径,因为下次您更改该文件时,哈希将发生变化。Frappe提供了一些助手来执行此操作。
# 在自定义HTML文件中包含资产
Jinja方法include_script和include_style将输出文件的正确路径,包括.js和.css文件的HTML标记。
index.html
<meta charset="utf-8"/>
<meta content="IE=edge"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>My App</title>
{{ include_style('style.bundle.css') }}
<div id="myapp"></div>
{{ include_script('main.bundle.js') }}
2
3
4
5
6
7
8
9
10
index.html (渲染后)
<meta charset="utf-8"/>
<meta content="IE=edge"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>My App</title>
<link href="/assets/myapp/dist/css/style.bundle.SYKETW5P.css" rel="stylesheet" type="text/css"/>
<div id="myapp"></div>
<script type="text/javascript" src="/assets/myapp/dist/js/main.bundle.BYJXV4LB.js"></script>
2
3
4
5
6
7
8
# 在app.html中包含资产
如果您想将/app中的打包资产从应用程序中包含,您可以使用app_include_js和app_include_css将它们加载到app.html。
[app]/hooks.py
app_include_js = ['main.bundle.js']
app_include_css = ['style.bundle.css']
2
# 获取打包资产路径
如果出于某种原因您只需要打包资产的路径,您可以使用bundled_asset Jinja方法来生成它。
Jinja
{{ bundled_asset('main.bundle.js') }}
渲染后
/assets/myapp/dist/js/main.bundle.BYJXV4LB.js
# Python API
这些API在Python中也可用。您可以从jinja_globals.py中导入它们。
from frappe.utils.jinja_globals import bundled_asset, include_script, include_style
bundled_asset('main.bundle.js')
2
3
# 在/app中延迟包含打包资产
如果您想在管理界面(/app)中延迟加载打包资产,您可以使用frappe.require方法。
frappe.require('main.bundle.js').then(() => {
// main.bundle.js现在已加载
})
2
3
这种方法在您想根据某些条件加载代码时很有用。第一次页面加载不会受到影响,对性能更好。
# 生产模式
将应用程序部署到生产环境时,您可以在生产模式下构建资产。在此模式下,打包器将压缩您的打包最终输出,从而实现更小的文件大小。
要生产模式下构建资产,请运行以下命令:
$ bench build --production