Get list of all fixtures/assets in javascript - javascript

I have a pretty common design pattern where I have a package that might have a fixture. Example:
Package.onUse(function (api) {
// ...
api.addAssets('fixture.json', 'server');
});
Now I am trying to make a package which consumes these packages and feeds in all of their fixtures (on the server).
I am wondering: is there a way to get all server side assets that have been added by a package? Eg, something like
Assets.getAll().forEach(function (asset) {
})

Related

How to share webpack result between frontend and backend?

I have two projects - frontend (vue) and backend (nodejs) - of one web app. I'm using webpack to build frontend. All images change their names to hashes during building. Now i need to know some of them at backend side. What is best way to share that info between frontend and backend?
I can use simple hardcoding approach or rely on custom hand-written mapping and use custom script to load assets. But both of these are fragile approach.
Webpack allows multi-build projects using target. Exactly, how to achieve this using Webpack?
Webpack programmatic can help you webpack Node API
// webpack/script.js
import webpack from "webpack";
const compiler = webpack({ /* your config*/ }, (err, stats) => {
// stats.toJson(options)
console.log(stats.toString())
// make api call for getting the info in backend with stats of your choice
})

How to get full list of Gatsby.js routes/endpoints in Cypress tests

I am currently writing some E2E tests with Cypress for a Gatsby based project.
For one test in particular, i'd like to loop through all pages of my Gatsby site, and in order to achieve this, I need a test fixture (e.g. endpoints.json) which includes an array of all urls.
I've tried the following methods (but all have limitations):
1. Running a node script to check the folder structure in the src/pages folder
Limitation - This doesn't account for dynamically generated pages in gatsby-node.js with graphql
2. Running a node script to scrape URLs in the sitemap.xml file generated with gatsby-plugin-sitemap
Limitation - The plugin only generated a sitemap.xml file in prod builds and not in dev (cypress runs a dev server)
Would be more than grateful if anyone has a suggestion for how we would get a full list of Gatsby endpoints in this environment.
You might just want to generate a file in the desired format on-build using the data in GraphQL:
// gatsby-node.js
const path = require("path")
const fs = require("fs").promises
exports.onPostBuild = async ({ graphql }) => {
const { data } = await graphql(`
{
pages: allSitePage {
nodes {
path
}
}
}
`)
return fs.writeFile(
path.resolve(__dirname, "all-pages.txt"),
data.pages.nodes.map(node => node.path).join("\n")
)
}
This creates a .txt file with each page’s path on a line. You could also just write out the data as JSON by passing in JSON.stringify(data.pages) as the second argument to writeFile, though.
There is a pretty cool new plugin for Cypress that will allow you to get the endpoints in your fixtures and env variable, called gatsby-cypress-endpoints. coreyward's answer is perfectly valid, but this should allow you to get the endpoints only when you run Cypress.
Please be aware that with more recent versions of Gatsby (particularly v3) you may have to set the env variable CI=true for the suggested solutions to work.
I believe this is because of changes to the development experience where pages & queries are processed on-demand instead of upfront.
The following flags FAST_DEV / QUERY_ON_DEMAND may be responsible for this behaviour.

Is there an all-in-one build system for dynamic react applications?

Build systems like next.js, razzle and back-pack seem really helpful, but based on examples I've found and the default applications they generate, they seem to be geared toward Server Side Rendering. Are there similar build systems that can (or can the ones mentioned here) be used to build dynamic react applications w/ node.js back-ends?
I'm hoping to find one I can run out of the box that will watch back-end and front-end code and refresh on a change to either. I know I can find a webpack or gulp script to start with and customize it, but I like the idea of a tool like the above that is just one command.
Edit
I need to deploy my front-end to Google Cloud Storage, so I don't want any server-side rendering at all.
You can export your next.js app as long as you only use features supported by export.
From the documentation:
https://github.com/zeit/next.js/#static-html-export
This is a way to run your Next.js app as a standalone static app without any Node.js server. The export app supports almost every feature of Next.js including dynamic urls, prefetching, preloading and dynamic imports.
Simply develop your app as you normally do with Next.js. Then create a custom Next.js config as shown below:
// next.config.js
module.exports = {
exportPathMap: function() {
return {
'/': { page: '/' },
'/about': { page: '/about' },
'/readme.md': { page: '/readme' },
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
}
}
}
In that, you specify what are the pages you need to export as static HTML.
Then simply run these commands:
next build
next export
On limitations:
Limitation
With next export, we build HTML version of your app when you run the command next export. In that time, we'll run the getInitialProps functions of your pages.
So, you could only use pathname, query and asPath fields of the context object passed to getInitialProps. You can't use req or res fields.
Basically, you won't be able to render HTML content dynamically as we pre-build HTML files. If you need that, you need run your app with next start.
If you don't need server side rendering you can go for create-react-app

Using imports, how does the server com with the client?

I'm confused by how we import [Publish] functions and [Meteor Methods] that reside under /imports/server to the Blaze client (either in /imports/client/ui or even just under app-name/client).
The classic way, is to just use the publish or meteor method, and everything is consumed by the client without imports. But if everything resides under the /imports directory (including the Blaze templates) how does that work? Are there real examples out there?
Illustration:
// imports/server/publishing/test.js
Meteor.publish('publish.test', function() {
if (this.userId) return TestCollection.find({});
return self.ready();
});
// imports/client/ui/test.js
import { Template } from "meteor/templating";
import { ReactiveDict } from "meteor/reactive-dict";
import { Mongo } from 'meteor/mongo';
import TestCollection from '../../imports/collections/test.js';
import "./test.html";
Template.Test.onCreated(function() {
this.state = new ReactiveDict();
this.autorun(() => {
const subscription = this.subscribe('publish.test');
...
}
});
});
How do server side only stuff make its way to the client in the new imports syle of developing?
UPDATE1:
Reponding to Answer1, would something like this work? Also, does the client look okay?
// app-name/imports/server/trades-pubs.js
// This code only runs on the server
Meteor.publish('trades', function tradesPublication() {
return Trades.find({},{sort: {timestamp: -1}, limit: 1000});
});
// app-name/imports/server/trades-methods.js
Meteor.methods({
// Only on server
'trades.importFromFiles'() {
fs = require('fs');
const path = "/home/daemmon/trades_data/";
var files = fs.readdirSync(path);
...
}
});
// app-name/server/main.js
import '../imports/server/trades-methods.js';
import '../imports/server/trades-pubs.js';
Is this all that's needed to get a publish methods to the client and server side meteor methods avaialbe to the client?
// imports/client/ui/test.js
import { Template } from "meteor/templating";
import { ReactiveDict } from "meteor/reactive-dict";
import { Mongo } from 'meteor/mongo';
import TestCollection from '../../imports/collections/test.js';
import "./test.html";
Template.Test.onCreated(function() {
this.state = new ReactiveDict();
this.autorun(() => {
const subscription = this.subscribe('trades');
...
}
});
});
UPDATE2:
you might want to consider importing app-name/imports/server/trades-methods.js somewhere in your client code as well, i.e. in a file like app-name/client/main.js
I thought we could not import server code on the client? If I wanted to import trades-methods.js for example, I'd have to move it to app-name/imports/api or something outside /imports/server.
UPDATE3:
Reading the Meteor Guide, I'm confused by this paragraph:
.
To fully use the module system and ensure that our code only runs when we ask it to, we recommend that all of your application code should be placed inside the imports/ directory. This means that the Meteor build system will only bundle and include that file if it is referenced from another file using an import (also called “lazy evaluation or loading”).
Meteor will load all files outside of any directory named imports/ in the application using the default file load order rules (also called “eager evaluation or loading”). It is recommended that you create exactly two eagerly loaded files, client/main.js and server/main.js, in order to define explicit entry points for both the client and the server. Meteor ensures that any file in any directory named server/ will only be available on the server, and likewise for files in any directory named client/. This also precludes trying to import a file to be used on the server from any directory named client/ even if it is nested in an imports/ directory and vice versa for importing client files from server/.
These main.js files won’t do anything themselves, but they should import some startup modules which will run immediately, on client and server respectively, when the app loads. These modules should do any configuration necessary for the packages you are using in your app, and import the rest of your app’s code.
.
Doesn't this mean for example that if there is a file inside the [/app-name/imports/server] directory, this file can NOT be imported in the client here [/app-name/client/main.js]?
.
For example I could NOT do the following:
Module inside the imports /server directory:
/app-name/imports/server/server-test.js
Module inside the imports /client directory:
/app-name/imports/client/client-test.js
.
Entry point in Meteor client:
/app-name/client/main.js
// => Would NOT work?
import { ServerTest } from "../../imports/server/server-test.js";
// => Would work?
import { ClientTest } from "../../imports/client/client-test.js";
UPDATE4:
Your wording here on your Update2:
Within the /imports folder, there are no special folder names - so you
can import a file from /imports/server in your client side code.
... is incorrect according to the author of this portion of the Meteor Guide.
First of all, since publications and methods are referenced only by their string name, they don't need to be imported in the code that subscribes to them or calls the functions. When doing Meteor.subscribe('publication') Meteor will try to find a publication named publication in the server, and subscribe to it. Same works with Meteor methods.
However, when using the /imports folder, your publications and methods need to be imported somewhere in server code so that Meteor loads them at all. The best practice to do this is to place a file somewhere in the imports folder, like /imports/startup/server/index.js (as recommended by the Meteor guide), where you simply import all files that declare publications and methods, and then importing this single file in some file outside the imports folder. For more about this, see the Meteor Guide and its example app.
Note also that for Meteor methods, you may want to include them also somewhere in your client code, so that the client can run simulations of them for optimistic UI before the server call returns. To do this, you can do the same as above but with a file like /imports/startup/client/index.js, that you include in the client code. I also recommend checking out the mdg:validated-method package, it makes using methods cleaner.
Update regarding the update in the question:
Yes, that seems like it would work, I think you got the point :)
As a minor detail, as I said, you might want to consider importing app-name/imports/server/trades-methods.js somewhere in your client code as well, i.e. in a file like app-name/client/main.js. This would enable the client to run a simulation of the method and update the UI immediately for better user experience. Don't do this if you don't want to expose some super-secret server code to the client though.
Update 2 in the question
Within the /imports folder, there are no special folder names - so you can import a file from /imports/server in your client side code. However, I do recommend placing code that is only meant for the server, like publications, in a folder named server, and not placing code that is meant to be used from both sides to a folder named server or client. Thus you might want to move your trades-methods.js file outside your /imports/server folder anyway. However this is only for clarity, Meteor does not care about folder names inside /server!
I really, really recommend you to read the Meteor guide, particularly the chapter on application structure and checking out the structure of the related example app. You'll save so much time in the long run!

I need a strongloop example wrote in javascript without angular

I want to have a strongloop example only using javascript without angular.
There's no complete working example without angular for now.
I want to simply include the browser.bundle.js in my index.html, then sync data from/to server side. In fact, I'm trying to replace pouchdb in my program since the couchdb seems not success in open source community.
I can't follow up this document correctly:
Running Loopback in the browser
create browser-app.js with the content from Running Loopback in the browser
copy past the content to browser-app.js
npm install loopback loopback-boot
browserify browser-app.js -o app.bundle.js Then I got error: Error: Cannot find module 'loopback-boot#instructions' from '/Users/simba/Projects/traveller-app/client/node_modules/loopback-boot'
There are few steps for this but its pretty simple.
Bootstrap your application via slc loopback.
Delete server/boot/root.js.
Uncomment two lines in server/server.js, it should look like:
...
// -- Mount static files here--
// All static middleware should be registered at the end, as all requests
// passing the static middleware are hitting the file system
// Example:
var path = require('path'); //this line is now uncommented
app.use(loopback.static(path.resolve(__dirname, '../client'))); //this line is now uncommented
...
Create index.html in the client dir (ie. client/index.html) with your contents.
That should get you a basic set up with just a basic front-end working. Let me know if you have any more issues.

Categories