337 karma · joined March 6, 2013
It's like atlas vs ark, not like unreal vs unity
JSON.parse(JSON.stringify(obj)) !== deepClone(obj)
EDIT: Also, how can you determine if the string should be a date, or a string? Sure, if it fits, you can always convert it to a Date, but if your first object is coming from something that sends ISO Dates as strings and you used JSON.parse with a reviver, you would get a different object.
> Share code between your SPAs, for example, utilities?
We alias a common folder for our utils with webpack which allows all our code to use the same utilities. We actually have two. One for shared frontend and backend, and one for just shared frontend
> What if your SPAs have large dependencies (React, Vue), should every SPA come with their own?
Webpack code splitting is how we split our apps. We also build into multiple bundles to keep bundle size small. That does mean that React does get bundled with each, but if you split thing appropriately, you can potentially save off a few MB with caching each bundle from page to page.
> Should every SPA have its own build tools?
With webpack, you can build all your bundles with one config / command
> What if there's an update to a library, should it be allowed that one SPA runs on an older library?
We have a root package.json for all of our react apps. This means that we don't update a library unless we can update it across the board. It takes more time to test upgrades, but it also means smaller bundles, easier package management and easier maintenance in the long run.
It’s a great product. The speed and ease of use is amazing.
EDIT: grammar hurts
> Starting from Gecko 30, this object is obsolete and should not be used anymore. Use the new Promise() constructor instead (or use the above backwards/forwards compatible Deferred function given below). For example, the equivalent of
Seems like it's obsolete. [0]
If you want to write async code, use async / await.
const run = async () => {
const response = await new Promise((resolve, reject) => methodOne(data, (e, res) => e ? reject(e) : resolve(res)));
};
If you spend enough time with fat arrow, it's as easy to read as `function` is. On top of that, IMO it looks cleaner. It also allows you to do scope binding in a different manor which in React is much better.This:
<a onClick={this.onClickEvent.bind(this)}>Click Me</a>
becomes this: <a onClick={(event) => this.onClickEvent(event)}>Click Me</a>
[0] https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_... new Promise(function (resolve, reject) {
methodOne(data, function (error, response) {
if (erorr) {
reject(error);
} else {
resolve(response);
}
})
})
vs new Promise((resolve, reject) => methodOne(data, (error, response) => error ? reject(error) : resolve(response)));I actually have better performance with Sublime Text and JavaScript than I do with vim and JavaScript. I wish that weren’t the case.
If you know if any better ways to get vim working with Syntastic for linting (eslint), I would love to know.
We have a custom script to deploy our own API Gateway using the AWS SDK and we generate a swagger file from simple json config files.
For the API Gateway issues, so far, we have a few things that are something we have to watch out for.
- All lambda endpoints through APIG are lambda proxy type. This means we can have a framework handle standard request / response stuff. The downside is that we can't support binary endpoints easily because they haven't fixed that issue yet.
- HTTP proxy pass through endpoints have to be added to the swagger somehow before we deploy. This is a little annoying, but not a huge issue
- Merge vs Override for deployments. We merge in beta, and override in other environments. This allows us to keep endpoints exactly as they are, but allow flexible testing in beta
1 APIG for 1 micro service isn't great IMO at scale since we run all our endpoints under on domain and mapping all of them would be a pain.
- src/project1/function1/
- src/project1/function2/
- src/project2/function1/
- src/project3/function1/
- src/project3/function2/
- src/project3/function3/
Deploying the functions is done by project, so we deploy all of one project, then move to the next, and so on and so forth.
A couple of things different that we do since we are building and then deploying to AWS:
- Build only on dedicated deployment branches (beta, qa, preview, prod)
- Build all functions (transpile, yarn, lint, etc) on every merge into the branch, but only deploy functions with different checksums (saves on api calls to AWS)
- We cache node_modules, but otherwise don't have any special build requirements and babel takes care of targeting node6.10 for Lambda
Total build time is between 8-13 minutes. There are some things we can do to speed up install that we haven't yet because it's not an issue yet but just a short list of things to note.
- Each function has it's own package.json for it's own packages. We maintain a list of npm packages that we download into a single folder first (that doesn't get deployed) to allow yarn to use those files from cache. We will eventually switch to an offline install for each function which essentially just copies the package folder and sets up anything it needs.
- We have a tarball package that includes all of our shared code / config files. Yarn seems to always want to download this file, regardless if we pre-download it.
- We deploy a single api endpoint for all of our micro services through API Gateway which cuts down on the time to deploy since API Gateway has a pretty hard throttle. This means we create a deployment on API Gateway every merge. We have one APIG for each environment
On top of that, I believe you can do a /2 CIDR which gives you over a million IPs to use. Not sure why you think that wouldn't be enough.