我正在尝试在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文件中缩进(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
中返回的是一个对象,而不仅仅是简单类型的字符串吗? - KeitelDOGFn::GetAtt
需要 2 个参数。格式可以是Fn::GetAtt: [资源的逻辑名称, 属性名称]
。官方文档: https://docs.amazonaws.cn/en_us/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html资源的逻辑名称(也称为逻辑 ID),其中包含您想要的属性。资源特定属性的属性名称,其值您想要获取。有关该资源类型可用属性的详细信息,请参阅资源的参考页面。 - KeitelDOGFn::GetAtt:["Storage","BucketName"]
中指定有效的Bucket属性,或任何其他属性名称。Fn :: GetAtt
是从模板中获取资源属性的函数,以使它们可重用。因此,我认为它必须在您的模板上存在,隐含地来自AWS模板或来自您的语法。S3 Bucket属性:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html - KeitelDOG