dark-kitt / wordpress-theme-vue
WordPress 的基础 Vue.js 主题
This package is auto-updated.
Last update: 2024-09-29 08:32:01 UTC
README
简介
这是一个示例 Vue/TypeScript 项目,使用 Webpack 打包,基于 第 1 部分 和 第 2 部分 的 WordPress 模板,可用于创建自定义 WordPress 主题。
您可以使用两种不同的方式与 WordPress 后端系统一起工作。第一种方式是将两个系统分开,这样您就有一个带有未连接前端系统的 无头后端。第二种方式是将两个系统一起用于 "岛屿架构",这样您仍然可以使用 WordPress 中的 PHP 文件并在您的 DOM 结构内部 激活动态 Vue 组件。
在我的情况下,我选择了第二种选项,并配置了所有必要的设置,使其适用于 "岛屿架构",但很容易修改项目以处理第一种方式并分离两个系统。只需安装 HtmlWebpackPlugin,以及一个模板引擎如 Handlebars 来渲染输出。之后,只需修改 Webpack 和 Apache 配置即可。
要求
安装
composer require dark-kitt/wordpress-theme-vue
如果您有特定的 /themes 目录路径,请将以下行添加到您的 composer.json 文件中。
"extra": { "installer-paths": { "path/to/themes/{$name}/": [ "type:wordpress-theme" ] }, "wordpress-install-dir": "path/to/wordpress" },
常见的 composer 命令
composer install composer update # package control composer require verdor/package composer remove verdor/package composer clear-cache composer show -i # installed packages
快速开始
安装所有必要的 node 模块。
yarn || npm i
开发模式。
yarn dev || npm run dev
生产模式。
yarn prod || npm run prod
如前所述,我只为 "岛屿架构" 创建了输出,这意味着您只能看到输出目录 (/www) 中的 JS、CSS 和必要的资产文件。因此,输出必须与 PHP 一起使用,例如,通过 WordPress 使用 wp_enqueue_script。
开始吧!
我想,最好的了解项目的方式是一起创建一个示例项目。以下说明基于 macOS 系统,但在一些故障排除之后,它也可能在 Windows 上工作。
像往常一样,我们先创建一个文件夹,然后更改目录。
mkdir example && cd example
设置环境
保持简单。前往 第1部分 下载WordPress模板,将项目作为ZIP文件下载,然后在项目根目录(/example)中打开并复制粘贴composer.json文件。如果您有GitHub账户并想通过curl获取文件,可以使用以下命令。
composer.json
curl --header "PRIVATE-TOKEN: <github_access_token>" "https://raw.githubusercontent.com/dark-kitt/wordpress-boilerplate/main/composer.json" > composer.json
或者,将您的私有访问令牌保存到curl头部文件中,例如~/.curl/github,并在命令中包含您特定的头部。
# ~/.curl/github
PRIVATE-TOKEN: <github_access_token>
curl -H @"$HOME/.curl/github" "https://raw.githubusercontent.com/dark-kitt/wordpress-boilerplate/main/composer.json" > composer.json
Composer
让我们继续。如果您有ACF Pro密钥,请手动将其添加到composer.json文件中[25](将<<ACF_KEY>>替换为您密钥)并调用composer update。否则,我们将移除ACF Pro并继续前进。让我们快速移除ACF Pro。为此,请调用以下命令。
composer config --unset repositories.advanced-custom-fields/advanced-custom-fields-pro && composer remove advanced-custom-fields/advanced-custom-fields-pro
现在,您的文件夹/文件结构应该如下所示。
/example
├── .env
├── composer.json
├── composer.lock
├── /vendor
├── ├── /...
├── /web
├── ├── /...
Docker
在下一步中,我们需要一个本地服务器。让我们使用Docker。如果您没有Docker,可以在这里下载:这里。设置Docker环境只需要3个文件。请复制粘贴以下片段,并在新项目的根目录(/example)中创建每个文件。
compose.yml
version: "3.9" services: webserver: container_name: wp-webserver build: context: . dockerfile: Dockerfile ports: - 80:80 volumes: - ./web:/var/www/html/web depends_on: - mysql-db environment: XDEBUG_CONFIG: remote_host=host.docker.internal mysql-db: container_name: wp-mysql image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ro_password MYSQL_USER: db_user MYSQL_PASSWORD: db_password ports: - "3306:3306"
Dockerfile
# Use an official PHP runtime FROM php:8.2-apache # Install necessary packages RUN apt-get update && apt-get install -y \ vim \ iputils-ping \ libzip-dev \ zip \ libpng-dev \ libicu-dev \ libmagickwand-dev RUN pecl install imagick # Install any extensions you need RUN docker-php-ext-install mysqli pdo pdo_mysql zip gd exif intl # Enable any extensions you need RUN docker-php-ext-enable imagick # Set the working directory to /var/www/html WORKDIR /var/www/html # Copy the required source code in the container at /var/www/html COPY --chown=www-data:www-data --chmod=755 ./web ./web COPY --chown=root:root --chmod=755 ./vendor ./vendor COPY --chown=root:root --chmod=755 ./.env ./.env # --- APACHE | set up --- # Enable APACHE modules RUN a2enmod rewrite && a2enmod ssl && a2enmod socache_shmcb # Copy new vhosts config file into the root dir COPY --chown=root:root --chmod=711 ./vhosts.conf ./vhosts.conf # Insert custom vhosts file RUN echo "Include /var/www/html/vhosts.conf" >> /etc/apache2/sites-available/vhosts.conf # Disable old default config file RUN a2dissite 000-default.conf # Enable new config file RUN a2ensite vhosts.conf # Docker PHP-APACHE container logs => docker logs wp-webserver # Set the 'ServerName' directive globally to suppress this message # NOTE: https://stackoverflow.com/questions/48868357/docker-php-apache-container-set-the-servername-directive-globally RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] # Describe which ports your application is listening on EXPOSE 80 # Get the Xdebug extension RUN pecl install xdebug \ # Enable the installed Xdebug && docker-php-ext-enable xdebug
vhosts.conf
<VirtualHost *:80> ServerName api.example.kitt ServerAlias www.api.example.kitt ServerAdmin webmaster@localhost DocumentRoot /var/www/html/web <Directory /var/www/html/web> Options Indexes FollowSymlinks AllowOverride All Require all granted </Directory> # deny the access for the theme config files (.env) <Directory /var/www/html/web/app/themes/example/config> Order deny,allow Deny from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <VirtualHost *:80> ServerName example.kitt ServerAlias www.example.kitt ServerAdmin webmaster@localhost DocumentRoot /var/www/html/web/app/themes/example <Directory /var/www/html/web/app/themes/example> Options Indexes FollowSymlinks AllowOverride All Require all granted </Directory> # deny the access for the theme config files (.env) <Directory /var/www/html/web/app/themes/example/config> Order deny,allow Deny from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
如你所见,我们在vhosts.conf文件中拒绝了对./web/app/themes/example/config目录的访问。这是很重要的,因为我们需要一个安全区域来配置我们的前端项目。但是,还有另一种方法。如果您不想扩展您的Apache vhosts.conf文件,您也可以在./web/app/themes/example/config目录中添加一个包含Deny from all的.htaccess文件。
之后,您的文件夹/文件结构应该看起来像这样。
/example
├── .env
├── compose.yml
├── composer.json
├── composer.lock
├── Dockerfile
├── /vendor
├── ├── /...
├── vhosts.conf
├── /web
├── ├── /...
⚠️ 解决自定义域所需的本地配置。
接下来,我们需要将本地域添加到我们的本地hosts文件中,以便在浏览器中解析自定义本地域。为此,您需要将localhost IP(127.0.0.1)添加到您的机器上的/etc/hosts文件。
打开一个新的终端窗口,并调用以下命令。
sudo vim /etc/hosts
输入您的机器密码,打开hosts文件。在文件末尾添加以下行。
# docker
127.0.0.1 example.kitt api.example.kitt
MySQL
在我们可以继续配置后端系统之前,我们需要设置数据库用户的权限。打开/启动您的(下载的)Docker应用程序,并在终端窗口中调用docker compose up。
docker compose up
安装所有必要的软件包并运行容器后,打开另一个终端窗口并连接到MySQL容器。
docker exec -it wp-mysql bash
以root用户登录。密码在compose.yml文件中定义,在我们的例子中是ro_password。
mysql -u root -p
现在,为db_user设置权限。
GRANT ALL PRIVILEGES ON *.* TO 'db_user'@'%' WITH GRANT OPTION;
刷新权限。
FLUSH PRIVILEGES;
登出。
quit
通过按ctrl + P和ctrl + Q取消到MySQL容器的连接。关闭新的终端窗口,以便我们再次只有一个窗口,其中运行着容器。
配置WordPress
最后,我们可以开始配置WordPress后端系统,并深入研究开始使用我们新的自定义WordPress主题的有趣部分。但在我们开始并尝试访问api.example.kitt域以打开后端系统之前,我们将退后一步。在终端窗口中按ctrl + C停止运行的容器。
容器停止后,我们需要设置.env和./web/.htaccess文件。请更新以下值。
.env
DB_HOST="wp-mysql" // same name as the container ... DB_NAME="wp_test" DB_USER="db_user" DB_PASSWORD="db_password" ... WP_HOME="http://example.kitt" ENV_SITEURL="http://api.example.kitt" ... WP_DEBUG_LOG="/dev/stderr" // docker error log dir ... JWT_AUTH_CORS_ENABLE=true
如果您已经有一个可用的PHPMailer电子邮件账户,您也可以设置以下值。
SMTP_HOST="smtp.domain.com" // "smtp.gmail.com" SMTP_AUTH=true SMTP_PORT=587 SMTP_SECURE="tls" SMTP_USERNAME="your@username.com" // "your@gmail.com" SMTP_PASSWORD="password" // your gmail password or app password SMTP_FROM="your@username.com" // "your@gmail.com" SMTP_FROMNAME="WordPress"
.htaccess
SetEnvIf Host ^ KITT_TLD=.kitt SetEnvIf Host ^ KITT_SLD=example
现在,需要重新构建容器。调用以下命令。
docker compose build
之后,我们将运行新的容器。
docker compose up
⚠️ 请注意,每次您编辑环境时,都需要重新构建您的容器。 ⚠️
让我们尝试访问我们的配置后的后端系统。打开您的浏览器并输入以下域名。
api.example.kitt
您应该看到一个WordPress的遮罩,您需要在其中输入您自定义后端系统的第一个值。我们将输入以下数据。
Site Title => example.kitt Username => admin Password => admin Confirm use of weak password => check Your Email => your@email.com Search engine visibility => check
点击安装WordPress按钮!并以管理员身份登录。在我们开始配置主题之前,我们需要激活我们的新自定义主题,您可以在外观下找到它。此外,我们还需要激活所有插件。
前端
让我们深入了解前端目录./web/app/themes/example,并配置WordPress的最后部分。我将从example.functions.php文件中取一些代码片段来处理一些配置。请在functions.php文件中添加以下行。
functions.php / 主题配置
/** debug */ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); global $wpdb, $wp_rewrite, $pagenow; $kitt_instance = KiTT\ThemeSetUp::get_instance(); $kitt_instance->set_up_theme( $wpdb, /** reqiured */ $wp_rewrite, /** reqiured */ $pagenow, /** reqiured */ [ 'set_up' => [ /** custom favicon, logos and login logo url */ 'favicon' => $kitt_instance->theme_url . '/src/assets/icons/vue-icon.png', 'login_logo' => $kitt_instance->theme_url . '/src/assets/icons/vue-icon.svg', 'login_logo_url' => WP_HOME, 'admin_bar_logo' => $kitt_instance->theme_url . '/src/assets/icons/vue-icon.svg', 'permalink_structure' => '/%postname%/', 'default_user_role' => 'editor', /** add or remove company settings menu page */ 'company_settings' => false ] ] ); $kitt_instance->post([ /** removes completely the default post section */ 'remove_post' => true ]); $kitt_instance->page([ 'page' => [ /** * info: * https://developer.wordpress.org/reference/functions/remove_post_type_support/ * * NOTE: * Gutenberg editor is always disabled */ 'remove_support' => ['excerpt', 'comments', 'trackbacks', 'author'], /** inspect the label attribute for="" in the screen options panel */ 'remove_meta_box' => ['commentsdiv', 'slugdiv'], /** en- or disable the SEO meta box */ 'SEO' => true, /** to enable tag support */ 'tag' => true, /** to enable category support */ 'category' => false ] ]); $kitt_instance->attachment([ 'attachment' => [ /** to enable tag support */ 'tag' => false, /** to enable category support */ 'category' => false, /** enable search duplicates support */ 'search_duplicates' => true ], /** * set custom upload mimes * * extend_defaults = true|false * true = merges the default upload mimes * false = replaces the default upload mimes * * list of defaulst: * https://developer.wordpress.org/reference/functions/get_allowed_mime_types/ */ 'upload_mimes' => [ 'extend_defaults' => true, 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', /** * NOTE: * the XML declaration is required * in each SVG file, otherwise * the SVG upload is not accepted * * enter the version and the encoding * charset at the top of each SVG file * * <?xml version="1.0" encoding="utf-8"?> * <svg xmlns="http://www.w3.org/2000/svg" ... viewBox="0 0 100 57"> * ... * </svg> */ 'svg' => 'image/svg+xml', 'pdf' => 'application/pdf', 'mp3|m4a|m4b' => 'audio/mpeg', 'mp4|m4v' => 'video/mp4', 'zip' => 'application/zip' ], 'options_media' => [ /** WP default 150x150px */ 'thumbnail_size' => [ 'thumbnail_size_w' => 150, 'thumbnail_size_h' => 150 ], /** WP default 1 */ 'thumbnail_crop' => 1, /** WP default 300x300px */ 'medium_size' => [ 'medium_size_w' => 300, 'medium_size_h' => 300 ], /** WP default 768x768px */ 'medium_large_size' => [ 'medium_large_size_w' => 768, 'medium_large_size_h' => 768 ], /** WP default 1024x1024px */ 'large_size' => [ 'large_size_w' => 1024, 'large_size_h' => 1024 ], /** WP default 0 */ 'uploads_yearmonth' => 1, /** WP default open */ 'ping_status' => 'closed', /** WP default open */ 'comment_status' => 'closed', /** /wp-content/uploads */ 'upload_path' => constant('WP_UPLOAD_DIR'), /** http://127.0.0.1/uploads */ 'upload_url_path' => constant('WP_UPLOAD_URL') ] ]); $kitt_instance->comments([ /** removes completely the default comments section */ 'remove_comments' => true ]); $kitt_instance->menu([ /** register main menu locations */ 'menu' => [ 'locations' => [ 'header' => 'Header' ] ] ]);
REST-API
在这个示例项目中,我们想使用REST API从后端系统中获取一些数据,因此我们也需要对其进行配置。请添加以下代码片段。
functions.php / REST-API配置
$kitt_instance->REST_API([ 'rest_api' => [ /** * set the namespace for your routes * => api.example.com/wp-json/->namespace<-/endpoint */ 'namespace' => explode('.', parse_url(WP_HOME)['host'])[0], /** removes the default REST API */ 'remove_default' => true, /** * examples: * 'Access-Control-Allow-Origin: ' . WP_HOME * 'Access-Control-Allow-Methods: POST, GET' * 'Access-Control-Allow-Credentials: true' * 'Access-Control-Max-Age: 600' */ 'headers' => [ 'Access-Control-Allow-Headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type', 'Access-Control-Allow-Origin: ' . WP_HOME, 'Access-Control-Allow-Methods: POST, GET', 'Access-Control-Allow-Credentials: true', 'Access-Control-Max-Age: 600' ], /** JWT token arguments */ 'token' => [ 'expiration_time' => time() + (DAY_IN_SECONDS * 7), 'header' => 'Access-Control-Allow-Headers, Access-Control-Allow-Origin, Content-Type, Authorization' ] ] ]);
如您所见,我已将Access-Control-Allow-Origin头设置为WP_HOME,这意味着只允许来自example.kitt的请求。这很重要,因为我们不希望其他网站可以访问数据。命名空间通过explode('.', parse_url(WP_HOME)['host'])[0]设置为example,因此如果您想对REST API发起请求,您需要调用api.example.com/wp-json/example/endpoint。
在我们添加REST API配置代码片段并重新加载后端系统后,我们需要创建一个REST API用户。转到用户并创建一个具有.env文件凭据的用户。在这种情况下,设置Username === REST_USER、Password === admin和Role === REST API User非常重要。
JWT令牌处理
显然,我们每个请求都需要一个令牌。为了检索令牌,我们现在将在functions.php文件中添加一个小的代码片段。让我们扩展实例并添加一个新的端点和回调函数来处理请求。
functions.php / 添加REST API端点
/** * register the /token endpoint to retrieve * the token from JWT Authentication for WP REST API */ $kitt_instance->rest_routes['token'] = [ /** * class WP_REST_Server { * ... * const READABLE = 'GET'; * const CREATABLE = 'POST'; * ... * } * * \WP_REST_Server::READABLE === GET * * documentation * https://developer.wordpress.org/reference/classes/wp_rest_server/ */ 'methods' => \WP_REST_Server::READABLE, 'callback' => 'get_token', // set the permission to public 'permission_callback' => '__return_true', // the args key is required even if the array is empty 'args' => [] ]; /** * define a custom callback function * to handle the request */ $kitt_instance->get_token = function () { $response= null; // create a simple curl request try { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, ENV_SITEURL . '/wp-json/jwt-auth/v1/token'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'username' => constant('REST_USER'), 'password' => constant('REST_PASSWORD') ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); } catch (Exception $e) { $response = $e->getMessage(); } // return the data return new \WP_REST_Response(json_decode($response), 200); };
我们做了什么?我们向$kitt_instance->rest_routes添加了一个新的端点,可以通过token调用(api.example.com/wp-json/example/token)。方法通过\WP_REST_Server::READABLE设置为GET。每个端点都需要一个权限回调。使用WordPress Theme Configuration插件,只能将权限设置为rest_api_user(受保护)或像我们这样的__return_true(公开)。之后,需要通过回调函数处理请求,该函数定义在$kitt_instance->rest_routes配置下方。您也可以在最后一个数组中添加一些参数,但在这个例子中,这不是必要的。
PHPMailer
如果您在.env文件中输入了电子邮件配置,您可以为PHPMailer添加以下代码片段进行配置,否则可以忽略此步骤。只需添加以下代码片段,并通过调用api.example.com/wp-json/example/email来测试端点。之后,您应该会收到自己的电子邮件。
functions.php / PHPMailer配置
/** * update email route arguments * set server settings * * update values with WP constants * or set your custom settings */ $kitt_instance->rest_routes['email']['args']['host'] = ['default' => constant('SMTP_HOST')]; // 'smtp.gmail.com' $kitt_instance->rest_routes['email']['args']['SMTP_auth'] = ['default' => constant('SMTP_AUTH')]; // boolean $kitt_instance->rest_routes['email']['args']['username'] = ['default' => constant('SMTP_USERNAME')]; // 'your@username.com' /** * use google app password: * https://support.google.com/accounts/answer/185833?hl=en */ $kitt_instance->rest_routes['email']['args']['password'] = ['default' => constant('SMTP_PASSWORD')]; // 'app-password' $kitt_instance->rest_routes['email']['args']['SMTP_secure'] = ['default' => constant('SMTP_SECURE')]; // 'tls' $kitt_instance->rest_routes['email']['args']['port'] = ['default' => constant('SMTP_PORT')]; // 587 /** PHPMailer debug */ $kitt_instance->rest_routes['email']['args']['debug'] = ['default' => false]; /** * test PHPMailer and send a mail to your own account via * http://api.example.com/wp-json/->namespace<-/email */ $kitt_instance->rest_routes['email']['args']['set_from'] = ['default' => [ 'address' => constant('SMTP_USERNAME'), 'name' => 'Foo' ]]; $kitt_instance->rest_routes['email']['args']['add_address'] = ['default' => [[ 'address' => constant('SMTP_USERNAME'), 'name' => 'Bar' ]]];
添加输出
如前所述,此示例项目使用了第二种方法来处理“岛屿架构”。因此,我们需要通过WordPress将输出文件添加到DOM中。让我们再添加一个片段。此时,我们将打开并编辑index.php文件。
index.php / 入队脚本和样式
// enqueue scripts and styles add_action('wp_enqueue_scripts', function () { if (file_exists('./www/assets-manifest.json')) { $manifest = json_decode(file_get_contents('./www/assets-manifest.json')); foreach ($manifest as $key => $value) { if ($key == 'entrypoints') { foreach ($value->main->assets->js as $js_file) { $js_file_info = pathinfo($js_file); // replace [hash].bundle.min for tag <script id="$id" ... $id = preg_replace('/(|\.\w+)\.bundle\.min/', '', $js_file_info['filename']); // enqueue the main.bundle.js file at the end of the DOM wp_enqueue_script($id, WP_HOME . '/www/' . $js_file, [], false, str_contains($js_file_info['filename'], 'main')); } foreach ($value->main->assets->css as $css_file) { $css_file_info = pathinfo($css_file); // replace [hash].bundle.min for tag <link id="$id" ... $id = preg_replace('/(|\.\w+)\.bundle\.min/', '', $css_file_info['filename']); wp_enqueue_style($id, WP_HOME . '/www/' . $css_file, [], false, 'screen'); } } } } });
正如您所看到的,我在输出目录(/www)内通过Webpack创建了一个manifest.json文件,并读取并添加了JSON文件中列出的所有脚本和样式。必须为每个文件添加一个ID,因此,我移除了hash,以便有可读的ID名称。我还为main.bundle.js文件创建了一个例外,该文件始终包含在DOM的末尾。
最后一点是请求一个令牌并将其交给前端系统。为此,我创建了一个全局常量。
<script> const TOKEN_DATA = <?= json_encode($kitt_instance->get_token()->data, JSON_PRETTY_PRINT) ?>; </script>
因此,最终我的index.php文件看起来是这样的。
index.php
<?php // Load WordPress for access of internal functions require_once('../../../wp/wp-load.php'); // enqueue scripts and styles add_action('wp_enqueue_scripts', function () { if (file_exists('./www/assets-manifest.json')) { $manifest = json_decode(file_get_contents('./www/assets-manifest.json')); foreach ($manifest as $key => $value) { if ($key == 'entrypoints') { foreach ($value->main->assets->js as $js_file) { $js_file_info = pathinfo($js_file); // replace [hash].bundle.min for tag <script id="$id" ... $id = preg_replace('/(|\.\w+)\.bundle\.min/', '', $js_file_info['filename']); // enqueue the main.bundle.js file at the end of the DOM wp_enqueue_script($id, WP_HOME . '/www/' . $js_file, [], false, str_contains($js_file_info['filename'], 'main')); } foreach ($value->main->assets->css as $css_file) { $css_file_info = pathinfo($css_file); // replace [hash].bundle.min for tag <link id="$id" ... $id = preg_replace('/(|\.\w+)\.bundle\.min/', '', $css_file_info['filename']); wp_enqueue_style($id, WP_HOME . '/www/' . $css_file, [], false, 'screen'); } } } } }); get_header(); ?> <main id="theme">WordPress index.php</main> <script> const TOKEN_DATA = <?= json_encode($kitt_instance->get_token()->data, JSON_PRETTY_PRINT) ?>; </script> <?php get_footer(); ?>
.env
最后一步是在主题目录的/configs内创建一个.env文件。请将.example.env文件复制并粘贴到./web/app/themes/example/configs目录中。
cp ./configs/.example.env ./configs/.env
好的,这有很多说明,但现在你已经完成了!只需使用yarn安装所有必要的包,并通过调用yarn dev启动前端系统。之后,所有必要的输出都应该在/www目录内创建,以便使我们的示例项目在example.kitt可见。
现在轮到你了。发挥创意,开始编码。只需将你的脚本和样式放在/src目录中,并创建你自己的自定义前端系统。
编码愉快!