@acanto/workflow 中文文档教程
Acanto Workflow
前端代码默认位于frontend
文件夹放在项目的根目录下。 所有内容都在标准的 October CMS 文件夹 /themes/acanto
中编译和组装,(请注意,活动主题名称应始终为 acanto
),其内容已被 gitignore。
Installation
建议通过克隆 存储库 October starter 来启动项目:
git clone git@git.acanto.net:acanto-framework/october-starter.git
然后进入项目根目录cd myproject
,然后:
npm i @acanto/workflow --save-dev
Setup project
在 npm install
之后,您可以运行 acanto start
来全面开发资产和模板,或者运行更轻的 acanto tpl
只是自动观看模板文件并将其复制到目标主题文件夹。 后一个命令被认为供后端开发人员使用,或者用于快速进行一些仅布局更改。 命令 acanto tpl
仅限于监视模板文件(twig 和 php)并在更改时构建它们,允许开发网站的框架而不需要对资产进行整体编译。 启动较重的 acanto start
时,始终会运行此命令。 可以随时添加页面运行acanto route route-name
或者acanto route route-one,route-two
来添加多条路由,已有的路由不会被覆盖,但是使用新的唯一路线 ID 时要小心。
Workflow commands
从您的根文件夹运行 acanto help
或 npm run help
以查看可用命令及其描述。
CI
部署时添加到 CI 脚本:
# install dependencies
npm install
# build the production code ready for deployment
npm run deploy
Configuration
全部gulp 配置在 npm 上发布的独立包 @acanto/workflow
中,该项目仅使用其 package.json
文件来配置和运行脚本。 这样一个项目只有一个devDependency
,脚本可以从每个项目中单独更新,这样每个项目都可以从更新中受益。
package.json
您可能希望将以下标准快捷方式添加到项目的 package.json
中:
"scripts": {
"start": "acanto start",
"build": "acanto build",
"tpl": "acanto tpl",
"route": "acanto route",
"component": "acanto component",
"core-sync": "acanto core-sync",
"test": "acanto test",
"deploy": "acanto deploy",
"help": "acanto help"
}
每个项目都可以从其 package 的
config
部分覆盖脚本的一些基本配置.json。 以下配置是必需的,需要根据您的特定项目进行相应更改:
"config": {
"favicons": {
"background": "#fefefe"
}
}
.env
如果未找到此文件,将自动生成试图猜测值(数据库用户名和密码的 execpt)
APP_URL=http://project.test
APP_API_URL=http://project.test/api
APP_DB_HOST=project.acanto.net
APP_DB_NAME=project_db
# APP_DB_USER=myuser
# APP_DB_PWD=mypassword
其他可用的配置变量在 env-example 文件。
一些依赖于环境的有用变量会自动始终可用于所有 js 和 scss 文件。
例如,在所有 SCSS 文件中:
$DEV: true; // or false
$ENV: "dev" | "stage" | "prod" | "preprod"; // as defined in the `APP_ENV` of the current .env file
$SRC_ASSETS: "../assets";
$URL_ASSETS: "https://myproject.com/themes/acanto/assets";
$SRC_FONTS: "../assets/fonts";
$URL_FONTS: "https://myproject.com/themes/acanto/assets/fonts";
$SRC_IMAGES: "../assets/images";
$URL_IMAGES: "https://myproject.com/themes/acanto/assets/images";
$SRC_SVGICONS: "../assets/svgicons";
在所有 JS 文件中,例如:
const __DEV__ = true; // or false
const __ENV__ = "dev" | "stage" | "prod" | "preprod"; // as defined in the `APP_ENV` of the current .env file
const __URL__ = "https://myproject.com";
const __API__ = "https://myproject.com/api";
const __ASSETS__ = "https://myproject.com/themes/acanto/assets";
const __FONTS__ = "https://myproject.com/themes/acanto/assets/fonts";
const __IMAGES__ = "https://myproject.com/themes/acanto/assets/images";
项目的所有 .js
文件将自动获得对这些变量的 IDE 支持(至少在 VScode 中):
Folder structure
中使用的每个路径可以在特定项目的 package.json
文件中覆盖构建脚本,但假设的理想和默认文件夹配置如下:
frontend/ # sources of all the frontend theme that gets compiled
assets
images/ # all images (will be compressed and generated webp format too)
media/ # all video and audio files
svgicons/ # svg images that will be turned automatically in an icon font
fonts/ # custom fonts for the specific theme
favicon.png # required image to automatically generate all favicons
config/ # configuration files
placeholders.scss # scss config (always accessible from any other file)
mixins.scss # scss config (always accessible from any other file)
variables.scss # scss config (always accessible from any other file)
index.js # js config (globals, settings, ecc.)
components/ # decoupled components to use across routes
Mycomponent/ # component folder uses component name
index.js # component script
index.php # component php template part
index.scss # component style
index.twig # component twig template part
core # folder to drop-in core elements from @acanto/frontend library, these are copied automatically to the /themes/acanto/partials folder allowing quick use with e.g. {% partial "element" %} or {% partial "custom-img" %}
element.twig
routes # route specific and inlined in the corresponding template
home
index.js # route specific and scoped scripts
index.php # route specific php template part
index.scss # route specific and scoped styles
index.twig # route specific twig template part
layouts # usually just one for project, but more layouts can e created and used independently within the same project with their entrypoint assets separately compiled
main # usually the standard layout to use in all templates
index.js # entry point with all common js/scss imports for this layout
index.php # common php data for this layout
index.scss # entry point with some simple scss for this layout
index.twig # base template for this layout
utils # utils generic components
a-utility-partial.twig # will be copied to /partials/utils
animations.scss # utils like styles
animations.js # utils simple script
vendor # custom vendor imports
package-name.js # customised vendor import script
package-name.scss # customised vendor import styles
themes/
acanto/
theme.yaml # only file that remains on git, needed by October and used as a placeholder to singla the presence of the theme. Everything else here is gitignored
assets/ # compiled static assets (scripts, styles, images, fonts, etc.) (.gitignored, DO NOT EDIT!)
layouts/ # twig layout templates (.gitignored, DO NOT EDIT!)
pages/ # twig page templates (.gitignored, DO NOT EDIT!)
home.htm # page specific template
partials/ # twig partials (.gitignored, DO NOT EDIT!)
data.htm # all core elements/templates get copied in the partials root folder
automated/ # compiled partials automatically generated by build scripts
components/ # decoupled components to use across pages
Mycomponent.htm # component template
这里有详细信息:
frontend/assets
该文件夹包含所有被操作、优化和复制的静态资产在 10 月的默认 themes/acanto/assets
文件夹中,它们是这样划分的:
- frontend/assets/fonts: all fonts files, they will get automatically optimized and content hashed. An
.htaccess
with long term expiration headers will be placed in this folder on build. - frontend/assets/images: all static theme images, they will get automatically optimized, content hashed and a
webp
additional format will be created forjpg
andpng
s (with same filename and different extension). An.htaccess
with long term expiration headers will be placed in this folder on build. - frontend/assets/media: all static theme video, audio and other files, their filenames will not be hashed. No
.htaccess
will be placed here. - frontend/assets/svgicons: all svg icons that will be optimized and inlined in an automated partial placed in
themes/acanto/partials/automated/svgicons.htm
to be usually included in thelayouts/main/index.twig
. They will be later used in the templates by using the handycore
partialicon
, for example with{% partial "icon" glyph='arrow_left' %}
- frontend/assets/favicon.png: required png image (1024x1024 is the optimal resolution) used to automatically generate all needed favicons. The script build an automated partial
themes/acanto/partials/automated/favicons.htm
to be usually included in thelayouts/main/index.twig
frontend/components
这个文件夹包含 components,它们是非常具体的 UI 片段,通常在同一个项目中重复使用并且可以但不一定需要在不同的项目中重复使用。 他们应该负责特定的功能,并且应该可以从外部进行配置,以允许在同一个项目中重复使用。 组件的常见用例是 UI 片段,例如 Header
、Footer
、Card
、Slider
、 ECC。
frontend/config
scss
文件(functions.scss
, mixins.scss
, variables.scss
, placeholders. scss
) 始终自动提供给整个项目文件。 这也是放置 JavaScript 全局配置的地方,例如断点、各种形式的数据、URL 等。
frontend/core
此文件夹包含非常通用且常用的核心元素案件。 它们通常重复包含在同一页面和同一网站中。 它们的灵活性应该允许在不同项目中使用它们,即使没有改变。 他们实际上应该负责基本和常见的元素和 UI,例如 forms
、images
、buttons
、typography
、 ECC。 此处的模板文件必须是扩展名.twig
(或.php
,如果需要但不鼓励)并且通常是从库 @acanto/frontend
使用命令 acanto core-sync< /代码>。
frontend/routes
此文件夹包含 Routes 代码,这些代码始终限定范围并仅输出到其特定模板。 所以这里写的JS和SCSS代码默认是不能干扰其他路由(或页面)的。
frontend/utils
在这里,我们应该将主要是 js/scss
utilities 的模板放在 layouts
、components
或者<代码>路线。 如果需要,这也是微型实用程序模板 .twig
的好地方,它们将被监视并复制到 partials
目录,因此在模板中可用 .twig
code>{% partial "utils/my-util" %}
frontend/vendor
这是放置 自定义供应商 文件的文件夹,这些文件由于各种原因不能由 npm< 添加和管理/代码>。 一个常见的用例是存在无法从公共
npm
存储库安装的高级 gsap
包。
Github workflow
- On branch
master
resides the stable development code - On branch
stage
resides the code deployed on thestaging
enviroment e.g.myproject.acanto.net
- On branch
production
is the production code publicly available at e.g.myproject.com
- Development happens initially on
master
and then, when more developers come in, specific work is done on specific branches branched frommaster
. It is important to often pull from there withgit pull origin master
to avoid problematic merge conflicts.
Caveats
Windows
要在 Windows 上运行脚本,您可能需要转到 System Properties
和 Advanced -> 添加到环境变量-> 用户-> Path
附加以下变量:
C:\Program Files\Git\cmd
in order to be able to install npm packages directly from git remotes instead that from published versions git must be in the path sourceC:\Program Files\nodejs
to run node scripts from the current directory
Workflow features
- Hot Module Replacement
- JS/SCSS modules bundling with
webpack
- SCSS compilation with
sass
andpostcss
- SCSS optimization combining media queries with
postcss-sort-media-queries
- ES6 syntax support with
babel
- CSS and JS files automatic splitting and cache busting (content hashed), this allows to long term expire-headers in the
.htaccess
- SCSS and JS sourcemaps
- Route and Layout specific JS/CSS through October's partials
- Assets minification
- Images minification and compression
- SVG inline icons automatic generation from
svg
images - Favicons auto-generation from single image
- License banner for compiled
css
andjs
files - Route and Component generator with
.js
,.scss
,.twig
and.php
templates
Development of @acanto/workflow
Notes
关于 assets 内联,如果文件大小小于 50kb,CSS 将被内联,如 AMP 规范所建议的那样。 JS 内联阈值设置为仅 2kb,请参阅这篇文章。
关于图像优化,考虑十月的 CMS 插件 offline-responsiveimages 和 webp-implementation
关于优化评估使用compression-webpack-plugin
关于 gzip 压缩 参见十月的 not-including-it - 默认原因在这里 https://github.com/octobercms/october/pull/1896,https://github.com/octobercms/october/pull/1885,https://github.com/octobercms/library/拉/201/提交/db2dec55ed7d42201f92b59e1de74b5c3196841c,https://github.com/octobercms/october/pull/1885/commits/86ca0c7e8d79a4a8f0662203b0b0b04cf549b6fc63,https://github.com/october84/cms/ com/forum/post/assets-gzip-compression
关于 polyfills babel 和 webpack 见:http s://github.com/babel/babel-loader#note-transform-runtime--custom-polyfills-eg-promise-library, https://github.com/zloirock/core-js#babel, https:/ /babeljs.io/docs/en/next/babel-preset-env.html#how-does-it-work, https://www.npmjs.com/package/polyfill-library
Bash utilities
- Convert all
.htm
files in folder to.php
withfind . -name "*.htm" -exec bash -c 'mv "$1" "${1%.htm}".php' - '{}' \;
- Run
start
with more RAMnode --max_old_space_size=8192 node_modules/@acanto/workflow/cli.js start
(@see similar issue)
Todo
- Maybe abstract CI deploy flow/steps into something like this
# deploy-AC-Usa-Ohio:
stage: deploy
only:
- stage
script:
- npm install --quiet
- npm run deploy:stage
- mkdir -p ~/.ssh
- echo "$AC_USA_OHIO_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- npm run deploy:rsync ubuntu@acusa.acanto.net:/var/www/acusa/
Acanto Workflow
Frontend code resides by default in the frontend
folder placed in the root of the project. Everything gets compiled and assembled in the standard October CMS folder /themes/acanto
, (note that the active theme name should always be acanto
) whose content is gitignored.
Installation
It is recomended to start a project by cloning the repository October starter with:
git clone git@git.acanto.net:acanto-framework/october-starter.git
Then go into the project root directory cd myproject
, then:
npm i @acanto/workflow --save-dev
Setup project
After npm install
you can either run acanto start
for full development of assets and templates or the lighter acanto tpl
to just automatically watch and copy the template files to the destination theme folder. This latter command is thought to be used either by backend developers or to quickly do some layout only changes. The command acanto tpl
is limited to watch over template files (twig and php) and build them on change, allowing to develop a skeleton of the website without the whole compilation of the assets. This command is always run when launching the heavier acanto start
. Pages can be added at any time running acanto route route-name
or acanto route route-one,route-two
to add multiple routes, existing routes will not be overwritten, but be careful of using a new unique route id.
Workflow commands
From your root folder run acanto help
or npm run help
to view the available commands and their description.
CI
When deploying add to the CI script:
# install dependencies
npm install
# build the production code ready for deployment
npm run deploy
Configuration
All gulp configuration is inside a standalone package @acanto/workflow
published on npm, the project just uses its package.json
file to configure and run the scripts. In this way a project have only one devDependency
and the scripts can be updated separately from each project, so that every project can benefit from the updates.
package.json
You might want to add to your project's package.json
the following standard shortcuts:
"scripts": {
"start": "acanto start",
"build": "acanto build",
"tpl": "acanto tpl",
"route": "acanto route",
"component": "acanto component",
"core-sync": "acanto core-sync",
"test": "acanto test",
"deploy": "acanto deploy",
"help": "acanto help"
}
Each project can override some basic configurations of the scripts from the config
section of it package.json
. The following configuration is required and needs to change accordingly to your specific project:
"config": {
"favicons": {
"background": "#fefefe"
}
}
.env
This file will be autogenerated if not found trying to guess the values (execpt for the db username and password)
APP_URL=http://project.test
APP_API_URL=http://project.test/api
APP_DB_HOST=project.acanto.net
APP_DB_NAME=project_db
# APP_DB_USER=myuser
# APP_DB_PWD=mypassword
Other configuration variables available are commented in the env-example file.
Some useful variables dependent on the environment are automatically made always available to all js and scss files.
Inside all SCSS files you have for instance:
$DEV: true; // or false
$ENV: "dev" | "stage" | "prod" | "preprod"; // as defined in the `APP_ENV` of the current .env file
$SRC_ASSETS: "../assets";
$URL_ASSETS: "https://myproject.com/themes/acanto/assets";
$SRC_FONTS: "../assets/fonts";
$URL_FONTS: "https://myproject.com/themes/acanto/assets/fonts";
$SRC_IMAGES: "../assets/images";
$URL_IMAGES: "https://myproject.com/themes/acanto/assets/images";
$SRC_SVGICONS: "../assets/svgicons";
Inside all JS files you have for instance:
const __DEV__ = true; // or false
const __ENV__ = "dev" | "stage" | "prod" | "preprod"; // as defined in the `APP_ENV` of the current .env file
const __URL__ = "https://myproject.com";
const __API__ = "https://myproject.com/api";
const __ASSETS__ = "https://myproject.com/themes/acanto/assets";
const __FONTS__ = "https://myproject.com/themes/acanto/assets/fonts";
const __IMAGES__ = "https://myproject.com/themes/acanto/assets/images";
All .js
files of your project will get automatically IDE support for these variables (at least in VScode):
Folder structure
Each path used in the build scripts can be overridden in the specific project package.json
file, but the ideal and default folder configuration assumed is the following:
frontend/ # sources of all the frontend theme that gets compiled
assets
images/ # all images (will be compressed and generated webp format too)
media/ # all video and audio files
svgicons/ # svg images that will be turned automatically in an icon font
fonts/ # custom fonts for the specific theme
favicon.png # required image to automatically generate all favicons
config/ # configuration files
placeholders.scss # scss config (always accessible from any other file)
mixins.scss # scss config (always accessible from any other file)
variables.scss # scss config (always accessible from any other file)
index.js # js config (globals, settings, ecc.)
components/ # decoupled components to use across routes
Mycomponent/ # component folder uses component name
index.js # component script
index.php # component php template part
index.scss # component style
index.twig # component twig template part
core # folder to drop-in core elements from @acanto/frontend library, these are copied automatically to the /themes/acanto/partials folder allowing quick use with e.g. {% partial "element" %} or {% partial "custom-img" %}
element.twig
routes # route specific and inlined in the corresponding template
home
index.js # route specific and scoped scripts
index.php # route specific php template part
index.scss # route specific and scoped styles
index.twig # route specific twig template part
layouts # usually just one for project, but more layouts can e created and used independently within the same project with their entrypoint assets separately compiled
main # usually the standard layout to use in all templates
index.js # entry point with all common js/scss imports for this layout
index.php # common php data for this layout
index.scss # entry point with some simple scss for this layout
index.twig # base template for this layout
utils # utils generic components
a-utility-partial.twig # will be copied to /partials/utils
animations.scss # utils like styles
animations.js # utils simple script
vendor # custom vendor imports
package-name.js # customised vendor import script
package-name.scss # customised vendor import styles
themes/
acanto/
theme.yaml # only file that remains on git, needed by October and used as a placeholder to singla the presence of the theme. Everything else here is gitignored
assets/ # compiled static assets (scripts, styles, images, fonts, etc.) (.gitignored, DO NOT EDIT!)
layouts/ # twig layout templates (.gitignored, DO NOT EDIT!)
pages/ # twig page templates (.gitignored, DO NOT EDIT!)
home.htm # page specific template
partials/ # twig partials (.gitignored, DO NOT EDIT!)
data.htm # all core elements/templates get copied in the partials root folder
automated/ # compiled partials automatically generated by build scripts
components/ # decoupled components to use across pages
Mycomponent.htm # component template
Here in details:
frontend/assets
This folders contains all static assets that gets manipulated, optimized and copied over the October's default themes/acanto/assets
folder, they are divided as such:
- frontend/assets/fonts: all fonts files, they will get automatically optimized and content hashed. An
.htaccess
with long term expiration headers will be placed in this folder on build. - frontend/assets/images: all static theme images, they will get automatically optimized, content hashed and a
webp
additional format will be created forjpg
andpng
s (with same filename and different extension). An.htaccess
with long term expiration headers will be placed in this folder on build. - frontend/assets/media: all static theme video, audio and other files, their filenames will not be hashed. No
.htaccess
will be placed here. - frontend/assets/svgicons: all svg icons that will be optimized and inlined in an automated partial placed in
themes/acanto/partials/automated/svgicons.htm
to be usually included in thelayouts/main/index.twig
. They will be later used in the templates by using the handycore
partialicon
, for example with{% partial "icon" glyph='arrow_left' %}
- frontend/assets/favicon.png: required png image (1024x1024 is the optimal resolution) used to automatically generate all needed favicons. The script build an automated partial
themes/acanto/partials/automated/favicons.htm
to be usually included in thelayouts/main/index.twig
frontend/components
This folder conain components that are quite specific pieces of UI which are usually reused within the same project and can, but not necessarily need, to be reused accross different projects. They should be responsible of specific functionalities and should be configurable from outside enought to allow their reuse in the same project. Usual use cases for components are pieces of UI like the Header
, the Footer
, Card
s, Slider
s, ecc.
frontend/config
The scss
files here (functions.scss
, mixins.scss
, variables.scss
, placeholders.scss
) are always made automatically available to the whole project files. This is also the place where to put JavaScript global configurations such as breakpoints, various forms of data, URLs etc.
frontend/core
This folder contain core elements that are very generic and of common use case. They are usually included repeatedly in the same page and across the same website. Their flexibility should allow to use them even without alteration across different projects. They should be in fact responsible of basic and common elements and UI like forms
, images
, buttons
, typography
, ecc. The template files here must be of extension .twig
(or .php
if necessary but discouraged) and are usually copy-pasted-tweaked from the library @acanto/frontend
with the command acanto core-sync
.
frontend/routes
This folder contains Routes code that is always scoped and outputted only to its specific template. So by default JS and SCSS code written here cannot interfere with other routes (or pages).
frontend/utils
Here we should put templates mostly js/scss
utilities to use and import where needed from either layouts
, components
or routes
. This is also a good place for tiny utils templates.twig
if needed, they will be watched and copied over to the partials
directory and therefore become available in templates to use with {% partial "utils/my-util" %}
frontend/vendor
This is the folder where to put custom vendor files that cannot for various reasons be added and managed by npm
. A common use case is the presence of the premium gsap
package that cannot be installed from the public npm
repository.
Github workflow
- On branch
master
resides the stable development code - On branch
stage
resides the code deployed on thestaging
enviroment e.g.myproject.acanto.net
- On branch
production
is the production code publicly available at e.g.myproject.com
- Development happens initially on
master
and then, when more developers come in, specific work is done on specific branches branched frommaster
. It is important to often pull from there withgit pull origin master
to avoid problematic merge conflicts.
Caveats
Windows
To run the script on windows you might need to go to System Properties
and on Advanced -> Add to Environment variables -> Users -> Path
append the following variables:
C:\Program Files\Git\cmd
in order to be able to install npm packages directly from git remotes instead that from published versions git must be in the path sourceC:\Program Files\nodejs
to run node scripts from the current directory
Workflow features
- Hot Module Replacement
- JS/SCSS modules bundling with
webpack
- SCSS compilation with
sass
andpostcss
- SCSS optimization combining media queries with
postcss-sort-media-queries
- ES6 syntax support with
babel
- CSS and JS files automatic splitting and cache busting (content hashed), this allows to long term expire-headers in the
.htaccess
- SCSS and JS sourcemaps
- Route and Layout specific JS/CSS through October's partials
- Assets minification
- Images minification and compression
- SVG inline icons automatic generation from
svg
images - Favicons auto-generation from single image
- License banner for compiled
css
andjs
files - Route and Component generator with
.js
,.scss
,.twig
and.php
templates
Development of @acanto/workflow
Notes
About assets inlining, CSS is inlined if the file size is minor than 50kb, as the AMP specification suggest. JS inline threshold is set to just 2kb instead, see this article.
About image optimization consider October's CMS plugins offline-responsiveimages and webp-implementation
About optimization evaluate the use of compression-webpack-plugin
About gzip compression see October's not-including-it-by-default reasons here https://github.com/octobercms/october/pull/1896, https://github.com/octobercms/october/pull/1885, https://github.com/octobercms/library/pull/201/commits/db2dec55ed7d42201f92b59e1de74b5c3196841c, https://github.com/octobercms/october/pull/1885/commits/86ca0c7e8d79a4a8f0662203b0b04cf549b6fc63, https://github.com/octobercms/october/issues/1847, https://octobercms.com/forum/post/assets-gzip-compression
About polyfills babel and webpack see: https://github.com/babel/babel-loader#note-transform-runtime--custom-polyfills-eg-promise-library, https://github.com/zloirock/core-js#babel, https://babeljs.io/docs/en/next/babel-preset-env.html#how-does-it-work, https://www.npmjs.com/package/polyfill-library
Bash utilities
- Convert all
.htm
files in folder to.php
withfind . -name "*.htm" -exec bash -c 'mv "$1" "${1%.htm}".php' - '{}' \;
- Run
start
with more RAMnode --max_old_space_size=8192 node_modules/@acanto/workflow/cli.js start
(@see similar issue)
Todo
- Maybe abstract CI deploy flow/steps into something like this
# deploy-AC-Usa-Ohio:
stage: deploy
only:
- stage
script:
- npm install --quiet
- npm run deploy:stage
- mkdir -p ~/.ssh
- echo "$AC_USA_OHIO_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
- chmod 600 ~/.ssh/id_dsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- npm run deploy:rsync ubuntu@acusa.acanto.net:/var/www/acusa/