I would like to take a param from a result of an external JS function but I retrieve this error:
Cannot resolve serverless.yml: Variables resolution errored with:
- Cannot resolve variable at "resources.Resources.FileBucket.Properties.BucketName": Value not found at "file" source
This is my (a piece) serverless file:
service: backend-uploader
frameworkVersion: '3'
variablesResolutionMode: 20210326
provider:
name: aws
runtime: nodejs16.x
region: eu-west-1
resources:
Resources:
FileBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
BucketName: ${file(./unique-bucket-name.cjs):bucketName}
This is my file unique-bucket-name.cjs in the same directory:
module.export = async function () {
return { bucketName: 'something' }
}
I have tried using self and importing the file as custom but the error still.
I have tried to use a Json with the same response and it works.
Why my JS file can't be taken from serverless?
Thanks.
Technically there's no much difference between using a JSON file to store the variables and a cjs. Looks like internally Serverless has some logic to parse the files and fetch the values
Serverless documentation points towards using a JSON file:
${file(./config.${opt:stage, 'dev'}.json):CREDS}
But, I've also seen some examples of people referencing to YML files instead.
Related
I am getting this error Module name "#google-cloud/vision" has not been loaded yet for context: _. Use require([]) ,when I run my project I have included require.js in my project and also the script tag in my html file <script data-main = "./app.js" src = "./libs/require.js"></script> , I went through many articles on require.js but couldn't understand what is the actual use of it and how I can resolve this error .
I also went through this thread on StackOverFlow but couldn't understand
Dynamic require in RequireJS, getting "Module name has not been loaded yet for context" error?
Here's my code
///////////////////////////////////////////////////////////////
//UPLOAD IMAGE to cloud bucket
function showResults(){
const bucketName = //name-of-bucket;
const filename = './img2.jpg';
// Imports the Google Cloud client library
const {Storage} = require('#google-cloud/storage');
// Creates a client
const storage = new Storage();
async function uploadFile() {
// Uploads a local file to the bucket
await storage.bucket(bucketName).upload(filename, {
// Support for HTTP requests made with `Accept-Encoding: gzip`
gzip: true,
// By setting the option `destination`, you can change the name of the
// object you are uploading to a bucket.
metadata: {
// Enable long-lived HTTP caching headers
// Use only if the contents of the file will never change
// (If the contents will change, use cacheControl: 'no-cache')
cacheControl: 'public, max-age=31536000',
},
});
console.log(`${filename} uploaded to ${bucketName}.`);
}
uploadFile().catch(console.error);
}
///////////////////////////////////////////////////////////////////
Your code is not compatible with RequireJS which uses AMD - Asynchronous Module Definition.
AMD format looks like this:
define(['#google-cloud/storage'], (storage) {
// body of your module here
});
The question is whether '#google-cloud/storage' is AMD compatible.
The simplest solution here would be to use more modern tooling like webpack or just use native ES6 modules if you support Chrome browser only
I am trying out Stitch, a serverless/hosted JavaScript environment from MongoDB. My main purpose is to help me learn modern JavaScript, but I am trying to write a useful app as well.
I have written the following function, and saved it in my Stitch app. I believe this follows the documented way to write functions in Stitch, and I have tested it from the Stitch administration console:
exports = function(query){
const http = context.services.get("HTTP");
const urlBase = context.values.get("stackOverflowApiUrl");
const options = [
'order=desc',
'sort=activity',
'site=stackoverflow',
'q=' + encodeURIComponent(query),
'user=472495',
'filter=!--uPQ.wqQ0zW'
];
return http
.get({ url: urlBase + '?' + options.join('&') })
.then(response => {
// The response body is encoded as raw BSON.Binary. Parse it to JSON.
const ejson_body = EJSON.parse(response.body.text());
return ejson_body.total;
});
};
This code is pretty simple - it obtains an http object for making external API fetches, and obtains a configuration value for a URL urlBase to contact (resolving to https://api.stackexchange.com/2.2/search/excerpts) and then makes a call to the Stack Overflow Data API. This runs a search query against my user and returns the number of results.
So far so good. Now, I want to call this function locally, in Jest. To do this, I have installed Node and Jest in a local Docker container, and have written the following test function:
const callApi = require('./source');
test('Simple fetch with no user', () => {
expect(callApi('hello')).toBe(123);
});
This fails, with the following error:
~ # jest
FAIL functions/callApi/source.test.js
✕ Simple fetch with no user (3ms)
● Simple fetch with no user
TypeError: callApi is not a function
2 |
3 | test('Simple fetch with no user', () => {
> 4 | expect(callApi('hello')).toBe(123);
| ^
5 | });
6 |
at Object.<anonymous>.test (functions/callApi/source.test.js:4:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.418s
Ran all test suites.
(In fact I was expecting it to fail, since it contains a global object context that Jest does not have access to. I will work out how to mock that later, but for now Jest cannot even see the function at all).
I suspect I can see the reason - in the Jest introduction docs, one has to do this for the SUT:
module.exports = function() { ... }
However the Stitch docs seem to require functions to be defined as:
exports = function() { ... }
I do not have a background in JavaScript to understand the difference. I could try module.exports in Stitch, but I would rather not, since this would either not work now, or cause a breakage in the future. Can Jest be instructed to "see" bare exports without the module prefix?
Incidentally, I have picked Jest because it is popular, and because some of my JavaScript colleagues vouch for it. However, I am not wedded to it, and would be happy to use something else if it is known to be better for Stitch development.
Update
Following the useful answer from jperl below, I find that the following construction is not possible in Stitch:
module.exports = exports = function() {}
I also cannot do this:
exports = function() {}
module.exports = exports
If I try either, I get the following error:
runtime error during function validation
So it looks like I have to get Jest to work without module.exports, or create a glue file that imports the exports version into module.exports, with the main file being used by Stitch, and the glue importer being used by Jest.
I suggest you to read this thread. And you're right in thinking it has to do with modules.exports vs exports. The thing is that module.exports and exports first point to the same thing. So something like this works:
//modify the same object that modules.exports is pointing to
exports.a = {}
exports.b = {}
but this won't:
exports = {}
Why? Because now exports points to something else than module.exports so what you're doing has no effect at all.
Update
Following some updates in the comments, we came to the view that Stitch does not seem to support the export format that Jest requires.
This is an addendum to jperl's answer, to show how I got Jest working while respecting Stitch's limitations.
Firstly, it is worth noting how a Stitch application is laid out. This is determined by the import/export format.
auth_providers/
functions/
function_name_1/
config.json
source.js
function_name_2/
config.json
source.js
...
services/
values/
The config.json file is created by Stitch remotely, and is obtained through a export. This contains ID information to uniquely identify the function in the same folder.
I believe it is common JavaScript practice to mix tests with source code, so I am following that style (I am new to modern JS, and I confess I find this style untidy, but I am running with it nevertheless). Thus I add a source.test.js file in each function folder.
Finally, since there is a discrepancy between what Stitch requires and what Jest requires, I have written a script to create a source code file under _source.js in each function folder.
So, each folder will contain these files (the underscore files will probably be ignored by Git, as they will always be generated):
_source.js
config.json
source.js
source.test.js
In order to create the underscored copies, I am using this shell script:
#!/bin/bash
# Copy all source.js files as _source.js
for f in $(find functions/ -name source.js); do cp -- "$f" "$(dirname $f)/_$(basename $f)"; done
# Search and replace in all _source.js files
for f in $(find functions/ -name _source.js); do sed -i -e 's/exports =/module.exports =/g' $f; done
A bit hacky perhaps, but it works!
Error screenshot:
While running react project by npm start, it shows error related to contentful.js. why does the package shows these types of error? I attached the screenshot with this post. How to solve this issue?
.env file
CONTENTFUL_ACCESS_TOKEN: process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN,
config file
import SETTINGS from "../env";
const contentfulClient = contentful.createClient({
space: SETTINGS.CONTENTFUL_SPACE,
accessToken: SETTINGS.CONTENTFUL_ACCESS_TOKEN
});
Do i need to enter api token anywhere?
.env
const SETTINGS = {
LANDING_BLOG_POSTS: "",
ICON_TYPE: "svg",
CONTENTFUL_SPACE: process.env.REACT_APP_CONTENTFUL_SPACE,
CONTENTFUL_ACCESS_TOKEN: process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN,
CLOUDINARY_UNSIGNED_PRESET: process.env.REACT_APP_CLOUDINARY_UNSIGNED_PRESET,
CLOUDINARY_CLOUD_NAME: process.env.REACT_APP_CLOUDINARY_CLOUD_NAME,
SERVER_7CHIP: process.env.REACT_APP_SERVER_7HIP || false,
HARD_CODED_USERNAME: process.env.REACT_APP_TOKEN_USERNAME || "**********",
HARD_CODED_PASSWORD: process.env.REACT_APP_TOKEN_PASSWORD || "************",
FACEBOOK_API_ID: process.env.REACT_APP_FACEBOOK_APP_ID,
FACEBOOK_PAGE_TOKEN: process.env.REACT_APP_FACEBOOK_PAGE_TOKEN,
FACEBOOK_PAGE_ID: process.env.REACT_APP_FACEBOOK_PAGE_ID || "**************",
FACEBOOK_SERVER_CALL: true
};
export default SETTINGS;
Since your code got as far as getting into the createClient function, that tells me your SETTINGS object is loading (otherwise you'd get a TypeError from accessToken: SETTINGS.CONTENTFUL_ACCESS_TOKEN). However the error message says that no accessToken was provided.
Therefore SETTINGS.CONTENTFUL_ACCESS_TOKEN is undefined, null or an empty string. Since that value is set to process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN this probably means that you have not set your REACT_APP_CONTENTFUL_ACCESS_TOKEN environment variable before running the program.
Try setting that environment variable to your access token value, then running the program.
If that works, you might want to reconsider the approach. You have an "env" file but is getting values from system environment variables. Usually you have an "env" file so that you can hardcode values into it, not rely on them being set externally. If they have to be set externally you might as well not use an "env" file and just use process.env.VARIABLE_NAME directly in your code.
Note that if you hardcode access tokens or other private information in an "env" file, you should add that file to .gitignore so that passwords/keys are not stored in git.
You created .env.development file same location as package.json file.
hope, this will help you.
For me, I had the variables in the .env file in the source directory and just had to source it. I ran . ./.env and that sorted out the error in my case.
In my case environment variables weren't accessible, because I created the .env file when my server was already running. I had to restart the server and everything worked like a charm.
I am quite new to nodeJS.
I am using the nodeJS module node-workflow
Basically, this module is an orchestrator that takes a custom javascript script (=workflow definition), then serialize it and store it in a REDIS db (for example), and execute on-demand later on by the node-workflow module.
A workflow definition is composed of task, like this:
var my_external_module = require('my_external_module');
var workflow = module.exports = {
name: 'Workflow Test',
chain: [{
name: 'TASK 1',
timeout: 30,
retry: 1,
body: function(job, cb) {
// Execute external function
my_external_module.hello("Monkey");
return cb(null)
},
},
...
First I put my function my_external_module.hello() in a .js file beside the workflow script.
When I run the node-workflow module I get the following error:
Error initializing runner:
[ReferenceError: my_external_module is not defined]
So I have created a module my_external_module,
and in: ./node_modules/my_external_module/index.js
module.exports = {
hello: function(name) {
console.log("Hello, " + name);
}
};
When I run the node-workflow module I get the same error:
Error initializing runner:
[ReferenceError: my_external_module is not defined]
It seems that the require(...) shall stands in one of the .js files of the node-workflow module, so I would have to hack one of the files of the module, but it is a bit dirty.
Is there something I missed?
Or is there a way to define a $PATH like in Python in order to my function to be accessible from everywhere.
You have to require it as:
var my_external_module = require('./my_external_module');
Notice the ./ this means Node should search for a file like ./my_external_module.js
If you omit the ./ Node looks at the installed modules on (usually) node_modules directory
I am trying to require a file with browserify using variables passed into a function:
var playersOptions = {
name: 'players',
ajax: 'team-overview',
route: {
name: 'overview',
path: 'playersOverview',
url: 'playersoverview'
}
};
var BackboneView = require(playersOptions.route.path);
//Error: Uncaught Error: Cannot find module 'playersOverview'
var BackboneView = require('playersOverview');
//Requires the file without any problems.
I am confused as to why this would fail? How can it not find the module when both are strings?
Browserify has to be able to statically analyze all of the require statements at build time so it can know what files it needs to include in the bundle. That requires that require can only be used with a string literal in the source code.
Instead of passing the name of a module around to require later, just pass the module itself:
var playersOptions = {
name: 'players',
ajax: 'team-overview',
route: {
name: 'overview',
module: require('playersOverview'),
url: 'playersoverview'
}
};
var BackboneView = playersOptions.route.module;
Even if this Browserify limitation wasn't present (eg. if you were using node.js directly), it's still a good idea to avoid passing module names to be required later because the require call could break if the module name passed to it had a path relative to the caller's directory and was passed into code in a file inside a different directory.