@acanto/workflow 中文文档教程

发布于 4年前 浏览 25 项目主页 更新于 3年前

Acanto Workflow

npm (scoped)

前端代码默认位于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 helpnpm run help 以查看可用命令及其描述。

acanto-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 中): js-constants-autocomplete

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 for jpg and pngs (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 the layouts/main/index.twig. They will be later used in the templates by using the handy core partial icon, 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 the layouts/main/index.twig

frontend/components

这个文件夹包含 components,它们是非常具体的 UI 片段,通常在同一个项目中重复使用并且可以但不一定需要在不同的项目中重复使用。 他们应该负责特定的功能,并且应该可以从外部进行配置,以允许在同一个项目中重复使用。 组件的常见用例是 UI 片段,例如 HeaderFooterCardSlider、 ECC。

frontend/config

scss 文件(functions.scss, mixins.scss, variables.scss, placeholders. scss) 始终自动提供给整个项目文件。 这也是放置 JavaScript 全局配置的地方,例如断点、各种形式的数据、URL 等。

frontend/core

此文件夹包含非常通用且常用的核心元素案件。 它们通常重复包含在同一页面和同一网站中。 它们的灵活性应该允许在不同项目中使用它们,即使没有改变。 他们实际上应该负责基本和常见的元素和 UI,例如 formsimagesbuttonstypography、 ECC。 此处的模板文件必须是扩展名.twig(或.php,如果需要但不鼓励)并且通常是从库 @acanto/frontend 使用命令 acanto core-sync< /代码>。

frontend/routes

此文件夹包含 Routes 代码,这些代码始终限定范围并仅输出到其特定模板。 所以这里写的JS和SCSS代码默认是不能干扰其他路由(或页面)的。

frontend/utils

在这里,我们应该将主要是 js/scss utilities 的模板放在 layoutscomponents 或者<代码>路线。 如果需要,这也是微型实用程序模板 .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 the staging 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 from master. It is important to often pull from there with git pull origin master to avoid problematic merge conflicts.

Caveats

Windows

要在 Windows 上运行脚本,您可能需要转到 System PropertiesAdvanced -> 添加到环境变量-> 用户-> 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 source
  • C:\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 and postcss
  • 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 and js 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-responsiveimageswebp-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 with find . -name "*.htm" -exec bash -c 'mv "$1" "${1%.htm}".php' - '{}' \;
  • Run start with more RAM node --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

npm (scoped)

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.

acanto-help

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): js-constants-autocomplete

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 for jpg and pngs (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 the layouts/main/index.twig. They will be later used in the templates by using the handy core partial icon, 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 the layouts/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, Cards, Sliders, 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 the staging 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 from master. It is important to often pull from there with git 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 source
  • C:\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 and postcss
  • 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 and js 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 with find . -name "*.htm" -exec bash -c 'mv "$1" "${1%.htm}".php' - '{}' \;
  • Run start with more RAM node --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/
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文