【发布时间】:2021-03-23 11:40:24
【问题描述】:
我正在尝试在 AWS 无服务器平台上部署我的 Laravel 应用程序,我在我的 laravel-mix 中使用动态导入和代码拆分来编译资产,执行此操作我按照bref package 文档中的步骤进行操作我按照指示安装了所需的库,我还将我的公共目录与我的 s3 存储桶同步
npm run prod
aws s3 sync public/ s3://<bucket-name>/ --delete --exclude index.php
并将我的.env 文件配置为:
MIX_ASSET_URL=https://<bucket-name>.s3.amazonaws.com
ASSET_URL=https://<bucket-name>.s3.amazonaws.com
接下来我将blade 文件配置为:
<script src="{{ asset('nits-assets/js/app.js') }}"></script>
我的webpack.mix.js 文件有:
const mix = require('laravel-mix')
const webpack = require('webpack');
const ASSET_URL = process.env.ASSET_URL + "/";
mix.js('resources/js/app.js', 'public/nits-assets/js')
.postCss('resources/sass/app.css', 'public/nits-assets/css', [
require("tailwindcss"),
])
.webpackConfig({
output: {
chunkFilename: 'nits-assets/chunks/[name].[contenthash].js',
publicPath: ASSET_URL
},
resolve: {
symlinks: false,
alias: {
NitsModels: path.resolve(__dirname, 'Models'),
},
},
plugins: [
new webpack.DefinePlugin({
"process.env.ASSET_PATH": JSON.stringify(ASSET_URL)
})
],
}).sourceMaps().version();
由于我将代码拆分为块,因此在获取块时遇到了麻烦,我最初的 app.js 文件从 s3 存储桶加载,但为了加载块,它尝试通过公共目录获取。
如何配置我的 laravel-mix 以从与我的公共目录同步的 s3 存储桶加载块?
编辑:
按照答案中的建议,我更改了 serverless.yml,它看起来像这样:
service: laravel
provider:
name: aws
# The AWS region in which to deploy (us-east-1 is the default)
region: ap-south-1
# The stage of the application, e.g. dev, production, staging… ('dev' is the default)
stage: dev
runtime: provided.al2
environment:
AWS_BUCKET: # environment variable for Laravel
Ref: Storage
iamRoleStatements:
# Allow Lambda to read and write files in the S3 buckets
- Effect: Allow
Action:
- s3:PutObject
- s3:ListBucket
- s3:GetObject
Resource:
- Fn::GetAtt: Storage.Arn # the storage bucket
- Fn::Join: [ '', [ Fn::GetAtt: Storage.Arn, '/*' ] ] # everything in the storage bucket
resources:
Resources:
Storage:
Type: AWS::S3::Bucket
package:
# Directories to exclude from deployment
exclude:
- node_modules/**
- public/storage
- resources/assets/**
- storage/**
- tests/**
functions:
# This function runs the Laravel website/API
web:
handler: public/index.php
timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
layers:
- ${bref:layer.php-74-fpm}
events:
- httpApi: '*'
# This function lets us run artisan commands in Lambda
artisan:
handler: artisan
timeout: 120 # in seconds
layers:
- ${bref:layer.php-74} # PHP
- ${bref:layer.console} # The "console" layer
plugins:
# We need to include the Bref plugin
- ./vendor/bref/bref
现在我得到了:
发生错误:ArtisanLambdaFunction - 属性变量的值必须是具有字符串(或简单类型)属性的对象。
编辑 2:
问题在于 serverless.yml 中的 indent(tab) 配置:
environment:
AWS_BUCKET: # environment variable for Laravel
Ref: Storage
iamRoleStatements:
# Allow Lambda to read and write files in the S3 buckets
- Effect: Allow
Action: s3:*
但现在有一个单独的问题:
错误:CloudFormation 模板无效:模板错误:每个 Fn::GetAtt 对象都需要两个非空参数,资源名称和资源属性
【问题讨论】:
-
之前没用过这个,但是在解析配置的时候某个地方,它期望对象中的所有值必须是简单类型或字符串,它找到了另一个对象,数组或函数,不能应用于流程。
-
它可以在属性
Resource: - Fn::GetAtt上返回一个对象而不是简单类型的字符串吗? -
@KeitelDOG 我修复了前一个问题,但现在我遇到了
Error: The CloudFormation template is invalid: Template error: every Fn::GetAtt object requires two non-empty parameters, the resource name and the resource attribute问题你能帮我解决这个问题吗? -
Fn::GetAtt需要 2 个参数。格式可以像Fn::GetAtt: [ logicalNameOfResource, attributeName ]。官方文档:docs.amazonaws.cn/en_us/AWSCloudFormation/latest/UserGuide/… 包含所需属性的资源的逻辑名称(也称为逻辑 ID)。您想要其值的资源特定属性的属性名称。有关该资源类型可用属性的详细信息,请参阅资源的参考页面。 -
检查模板结构。真的有resources.Resources吗?也许您只想指定 Resources.Storage [type: AWS::S3::Bucket , ...] 并在
Fn::GetAtt: [ "Storage", "BucketName" ]或任何其他属性名称中指定 Bucket 的有效属性。Fn::GetAtt是一个函数,它在模板中获取资源的属性,以使它们可重用。因此,我认为它必须存在于您的模板中,隐含地来自 AWS 模板或您的语法。 S3 存储桶属性:docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
标签: laravel webpack laravel-mix aws-serverless bref