# 资产打包

理解Frappe框架中静态资产打包的工作方式的指南。

Frappe提供了一个在/app上可用的丰富的管理界面,这是一个用现代JavaScript语法编写的单页应用程序(SPA),样式是用SASS (.scss)文件编写的。这些文件浏览器无法直接理解,因此需要在发送到浏览器解析和执行之前进行编译。

Frappe自带了一个资产打包器,可以编译客户端资产,如:

  • .js(带有importexport的现代语法)
  • .ts(TypeScript文件)
  • .vue(Vue单文件组件)
  • .css(使用PostCSS处理的CSS)
  • .scss(SASS文件)
  • .sass(使用缩进语法的SASS文件)
  • .styl(Stylus文件)
  • .less(Less文件)

这些文件根据类型编译为.js.css,并发送到浏览器。

# 构建资产

要使用资产打包器编译资产,您需要从frappe-bench文件夹运行以下命令:

$ bench build
1

您也可以通过提供--apps选项仅运行特定应用程序。

# 仅构建frappe资产
$ bench build --apps frappe

# 仅构建frappe和erpnext资产
$ bench build --apps frappe,erpnext
1
2
3
4
5

# 监视模式

当您使用打包文件时,您需要构建命令在您每次更改源文件时都运行。资产打包器提供了一个监视模式,它会监听文件系统的变化,并在文件变化时重新构建。

运行以下命令将启动一个长时间运行的过程,它监视您的文件并在它们变化时重新构建。每次重新构建时,它会记录一行包含文本"Compiled changes..."的日志。

$ bench watch
监视更改...
下午1:17:28:编译更改...

1
2
3
4

您也可以通过提供--apps选项仅运行特定应用程序。

# 仅监视erpnext资产
$ bench watch --apps erpnext
1
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/jsdist/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
1
2

现在,您可以在您的源文件中这样导入它:

myapp/public/main.bundle.js

import * as dayjs from 'dayjs';

console.log(dayjs())
1
2
3

# 在HTML中包含打包资产

当打包文件被编译时,输出文件包含一个唯一的哈希。因此,您不能硬编码文件的路径,因为下次您更改该文件时,哈希将发生变化。Frappe提供了一些助手来执行此操作。

# 在自定义HTML文件中包含资产

Jinja方法include_scriptinclude_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') }}
1
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>

    &lt;script type="text/javascript" src="/assets/myapp/dist/js/main.bundle.BYJXV4LB.js"&gt;&lt;/script&gt;
1
2
3
4
5
6
7
8

# 在app.html中包含资产

如果您想将/app中的打包资产从应用程序中包含,您可以使用app_include_jsapp_include_css将它们加载到app.html。

[app]/hooks.py

app_include_js = ['main.bundle.js']
app_include_css = ['style.bundle.css']
1
2

# 获取打包资产路径

如果出于某种原因您只需要打包资产的路径,您可以使用bundled_asset Jinja方法来生成它。

Jinja

{{ bundled_asset('main.bundle.js') }}
1

渲染后

/assets/myapp/dist/js/main.bundle.BYJXV4LB.js
1

# Python API

这些API在Python中也可用。您可以从jinja_globals.py中导入它们。

from frappe.utils.jinja_globals import bundled_asset, include_script, include_style

bundled_asset('main.bundle.js')
1
2
3

#/app中延迟包含打包资产

如果您想在管理界面(/app)中延迟加载打包资产,您可以使用frappe.require方法。

frappe.require('main.bundle.js').then(() => {
  // main.bundle.js现在已加载
})
1
2
3

这种方法在您想根据某些条件加载代码时很有用。第一次页面加载不会受到影响,对性能更好。

# 生产模式

将应用程序部署到生产环境时,您可以在生产模式下构建资产。在此模式下,打包器将压缩您的打包最终输出,从而实现更小的文件大小。

要生产模式下构建资产,请运行以下命令:

$ bench build --production
1
最后更新时间: 9/27/2024, 3:24:28 PM