Not using initializeApp for firebase with webpack - javascript

currently my app does not use the firebase initialiseApp in the config, as it gets its config from <script src="/__/firebase/init.js"></script>.
Now, I am wanting to start using webpack, and so I will not be using that script anymore. However, I use multiple firebase enviroments for my app, and so this init.js is very useful, as I do not have to hard code the config inside a js file.
Is there any alternative from the provided init.js for module bundlers?

Related

Preparation work before executing the app Plesk NodeJS

I'm trying to deploy an Api Rest that was build on NodeJS Express and when I try to make the deploy process, I got this error. I don't know hoy can I solve this:
The problem is that you are importing some modules in your app.js with the import function, but you can't do that because you are stating in your config to treat your js files as module, to import external modules inside ES modules you should use the following structure:
"import { something } from /path/to/module"
Let me know if it solved your problem!

Natively import ES module dependencies from npm without bundling/transpiling first-party source

Background
I'm trying to create a "buildless" JavaScript app, one where I don't need a watch task running to transpile JSX, re-bundle code, etc every time I save any source file.
It works fine with just first-party code, but I'm stuck when I try to import dependencies from npm.
Goal
I want to achieve this kind of workflow:
npm install foo (assume it's an ES module, not CommonJS)
Edit source/index.js and add import { bar } from 'foo'
npm run build. Something (webpack, rollup, a custom script, whatever) runs, and bundles foo and its dependencies into ./build/vendor.js (without anything from source/).
Edit index.html to add <script src="build/vendor.js" type="module"...
I can reload source/index.js in my browser, and bar will be available. I won't have to run npm run build until the next time I add/remove a dependency.
I've gotten webpack to split dependencies into a separate file, but to import from that file in a buildless context, I'd have to import { bar } from './build/vendor.js. At that point webpack will no longer bundle bar, since it's not a relative import.
I've also tried Snowpack, which is closer to what I want conceptually, but I still couldn't configure it to achieve the above workflow.
I could just write a simple script to copy files from node_modules to build/, but I'd like to use a bundled in order to get tree shaking, etc. It's hard to find something that supports this workflow, though.
I figured out how to do this, using Import Maps and Snowpack.
High-Level Explanation
I used Import Maps to translate bare module specifiers like import { v4 } from 'uuid' into a URL. They're currently just a drafted standard, but are supported in Chrome behind an experimental flag, and have a shim.
With that, you can use bare import statements in your code, so that a bundler understands them and can work correctly, do tree-shaking, etc. When the browser parses the import, though, it'll see it as import { v4 } from 'http://example.org/vendor/uuid.js', and download it like a normal ES module.
Once those are setup, you can use any bundler to install the packages, but it needs to be configured to build individual bundles, instead of combining all packages into one. Snowpack does a really good job at this, because it's designed for an unbundled development workflow. It uses esbuild under the hood, which is 10x faster than Webpack, because it avoids unnecessarily re-building packages that haven't changed. It still does tree-shaking, etc.
Implementation - Minimal Example
index.html
<!doctype html>
<!-- either use "defer" or load this polyfill after the scripts below-->
<script defer src="es-module-shims.js"></script>
<script type="importmap-shim">
{
"imports": {
"uuid": "https://example.org/build/uuid.js"
}
}
</script>
<script type="module-shim">
import { v4 } from "uuid";
console.log(v4);
</script>
snowpack.config.js
module.exports = {
packageOptions: {
source: 'remote',
},
};
packageOptions.source = remote tells Snowpack to handle dependencies itself, rather than expecting npm to do it.
Run npx snowpack add {module slug - e.g., 'uuid'} to register a dependency in the snowpack.deps.json file, and install it in the build folder.
package.json
"scripts": {
"build": "snowpack build"
}
Call this script whenever you add/remove/update dependencies. There's no need for a watch script.
Implementation - Full Example
Check out iandunn/no-build-tools-no-problems/f1bb3052. Here's direct links to the the relevant lines:
snowpack.config.js
snowpack.deps.json
package.json
core.php outputs the shim
plugin.php - outputs the import map
passphrase-generator.js - imports the modules. (They're commented out in this example, for reasons outside the scope of this answer, just uncomment them, run the bundle script, and they'll work).
If you are willing to use an online service, the Skypack CDN seems to work nicely for this. For instance I wanted to use the sample-player NPM module and I've chosen to use a bundle-less workflow for my project using only ES6 modules as I'm targeting embedded Chromium latest version so don't need to worry about legacy browser support, so all I needed to do was:
import SamplePlayer from "https://cdn.skypack.dev/sample-player#^0.5.5";
// init() once the page has finished loading.
window.onload = init;
function init() {
console.log('hello sampler', SamplePlayer)
}
and in my html:
<script src="./src/sampler/sampler.js" type="module"></script>
And of course you could just look inside the JS file the CDN generates at the above url and download the generated all-in-one js file it points to, in order to use it offline as well if needed.

ASP .Net Core 3.1 octokit rest npm package issues

I use npm and a gulpfile.js to essentially export npm packages to a 'lib' folder under 'wwwroot'; this works a treat and whenever I update a specific npm package if it's in my gulpfile.js watch list it'll push the contents to the 'lib' folder.
The issue I have is that I used to use a manually extracted copy of ocktokit-rest in order to query the public api for some repo data. Recently this has stopped working, I assume that GitHub has updated their api which has had some breaking changes for my old version of ocktokit-rest. So with that in mind I installed #Ocktokit/rest version 18.0.9 using the npm package.json. This then creates the following directory:
~/lib/#octokit/rest/
According to the docs I need to refence one of the index.js files inside this. So because Razor doesn't appreciate the use of the # symbol in the path I use the following in my _layout.cshtml
<script src="#Url.Content("~/lib/#octokit/rest/dist-src/index.js")" type="module"></script>
I added the type="module" as I was initially getting some issues with the import statements inside of the index.js file.
Here's the index.js file contents at the above route:
import { Octokit as Core } from "#octokit/core";
import { requestLog } from "#octokit/plugin-request-log";
import { paginateRest } from "#octokit/plugin-paginate-rest";
import { restEndpointMethods } from "#octokit/plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
userAgent: `octokit-rest.js/${VERSION}`,
});
This then raises the following error in the chrome debugger:
Uncaught TypeError: Failed to resolve module specifier
"#octokit/core". Relative references must start with either "/", "./",
or "../".
I don't particularly like the idea of adjusting the #octokit/ reference in favour of '../../' because then every time my gulpfile.js npm push task runs I'll have to manually change this file. However for the sake of debugging this I went through and adjusted index.js to look like this:
import { Octokit as Core } from "../../core";
import { requestLog } from "../../plugin-request-log";
import { paginateRest } from "../../plugin-paginate-rest";
import { restEndpointMethods } from "../../plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
userAgent: `octokit-rest.js/${VERSION}`,
});
When I did this I got similar error messages for each import that looked something like this:
index.js:4 GET
https://localhost:44364/lib/#octokit/plugin-rest-endpoint-methods
net::ERR_ABORTED 404
Now the above URL is pointed at the directory not a specific file, if I run the above through to a single file I can see it load in the browser and display the file. So If I type:
https://localhost:44364/lib/#octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
I can see the js file displayed in the browser so I know it can be pathed to. Now Ideally I want to be able to use this package in another bit of custom js I wrote that iterates through my repos and creates nice little cards with all the info on, so I'm basically just trying to use it like this:
var octokit = new Octokit({ userAgent: 'agentName' });
But obviously the above is complaining about the existence of Octokit.
So I guess my question is, what the frack? I'm obviously missing something here so if anyone has any ideas in what direction I need to look or research I'd be very grateful.
It's probably nothing to do with the octokit package at all, and much more likely that I just don't understand how to properly import these types of JavaScript libraries into my asp .net core solution
There's a few parts of adding Octokit that you're having difficulties with: handling the # symbol, the scope at which you import it, and the fact that you're trying to use files intended for build tools.
# in a Razor Page
When you're writing JavaScript inline in a <script> tag inside the context of a Razor page, you'll need to escape the # character by using ##. For example, if you were referencing the Octokit path, you would write ##octokit/rest.
Scope
When you're using type=module, your code has module scope, making you unable to reference the Octokit variable outside of the module. In order to break out of module scope, you can attach the Octokit variable to the window object:
window.Octokit = new Octokit({ userAgent: 'agentName' });
Then later on, your code in other script blocks can access Octokit like normal:
const { data } = await Octokit.request("/user");
Building Octokit
The files you're importing are not intended for direct consumption by the browser. It's expecting you to be importing it into JavaScript build tools, not importing it as a module directly from the browser.
The index.js file you're trying to import client side is intended to be used with some JavaScript build tools like Webpack. To get this working the way you want to in gulp, you would need to modify your gulpfile.js to include some kind of a plugin that would import #octocat/rest and output it into a file usable by a browser.
To do this with Webpack, you need to install a Webpack plugin for gulp:
npm install --save-dev webpack-stream gulp-rename
Then, create a file next to your gulpfile.js called index.js that imports the library and does something with it:
import { Octokit } from "#octokit/rest"
window.Octokit = new Octokit({ userAgent: 'agentName' });
Now, modify your gulpfile.js to take index.js and pipe it through the webpack plugin:
const gulp = require('gulp');
const webpack = require('webpack-stream');
const rename = require('gulp-rename');
gulp.task('default', () =>
gulp.src(['index.js'])
.pipe(webpack())
.pipe(rename("index.js"))
.pipe(gulp.dest('lib/octokit/rest/'))
);
After running gulp, you should have an output file that has resolved all of the dependencies necessary for #octokit/rest!
Alternative Solutions
To save the trouble for this specific package, could you instead load Octokit from their CDN? The CDN handles all of the building and package resolution for you. Your code could then be:
<script type="module">
import { Octokit } from "https://cdn.skypack.dev/##octokit/rest";
window.Octokit = new Octokit({ userAgent: 'agentName' });
</script>
(Note that ## will escape the # sign on Razor pages.)
Most packages offer a CDN option for loading their library client side without having to mess around with build tools. Even if they don't officially offer a CDN, sites like jsdelivr or unpkg can still offer a way to import these files.
Sometime in the future, it looks like browsers might support import-maps. Then, you would be able to handle the package resolution through the browser and do something like this on your Razor page:
<script type="importmap">
{
"imports": {
"/##octokit": "/lib/##octokit/"
}
}
</script>
<script type="module">
import { Octokit } from '##octokit/rest';
var octokit = new Octokit({ userAgent: 'agentName' });
</script>
It looks like this might be usable with a polyfill like system-js, where you would add the s.js loader and replace importmap with systemjs-importmap.

Attempting to load a JavaScript sdk into an Angular2 application. Can't find all dependencies

I'm attempting to make use of this library: https://github.com/MagicTheGathering/mtg-sdk-javascript in an Angular2 application.
Unfortunately, I've been going in circles trying to load it into my application.
Firstly, on the TypeScript side if I import it using:
import { } from 'mtgsdk';
there are no types to load into the {}.
If I attempt to load it using something similar to:
import * as mtg from 'mtgsdk'
I'm unable to because it says that it's unable to find a module named mtgsdk.
I've installed the module using
npm install --save mtgsdk
Also, npm installs work fine for other modules.
The application compiles fine if I load it in using require via something similar to this:
var mtg = require('mtgsdk');
Taking that approach, I'm able to compile and launch but in the browser I get a number of errors about modules that it can't find. I figure they are prerequisites for the sdk that didn't get loaded so I start bringing them in via package.json.
For every one that I bring in, I then have to go to systemjs.config.js and add an entry pointing to the module's entry point and often have to specify a default extension using blocks like this:
pointer
'mtgsdk': 'npm:mtgsdk/lib/index.js',
'request-promise': 'npm:request-promise/lib/rp.js',
'ramda': 'npm:ramda/dist/ramda.js',
'emitter20': 'npm:emitter20/index.js',
'bluebird': 'npm:bluebird/js/browser/bluebird.js',
'request': 'npm:request/index.js'
default extension
'request-promise':
{
defaultExtension: 'js'
}
I'm not sure if that's the right approach though because the more dependencies I add, the more that I end up requiring. At one point I had literally gotten up to 50 extra dependencies added because every time I launched, the browser console would find more that were needed.
Is there any easier way to load all of these in?
Also, some of them (such as tough-cookie and request-promise-core) were very problematic to load and I couldn't get the browser console to stop complaining about them. Finally, some of them seemed very basic such as url, http, https. Those seem like they should already be present.
Using systemjs was utilized in the previous versions of Angular 2, However Angular 2 has evolved to Angular 4, with super new features like Angular CLI.
I recommend your use Angular CLI, with #angular/cli.
Importing Node modules
Since mtgsdk is a node-module, you can easily import it using
import * as mtg from 'mtgsdk'
However for your program to compile, you must install a type definition for it. or declare one for it in /typings.json or your app might not build.
Importing Client Scripts
For client scripts like firebase.js you won't need to add client scripts as entries in systemjs.config.js again.
Using #angular/cli, you would easily add them in the scripts[] array in your angular-cli.json for automatic compilation.
Then access them like this
declare const firebase: any;
Here is a quickstart tutorial to set up Angular with #angular/cli.

webpack json-loader fails in lernajs controlled dependencies

I'm using lernajs to manage a monorepo. There, I have two packages:
app (via create-react-app)
lib (a react component transpiled with babel-cli)
When adding require('./package.json') to app, webpack compiles as expected. The json file is loaded as expected. However, when I put require('./package.json') into the lib package, webpack fails with Module not found: 'json'. The json loader is working fine for dependencies not controlled by lernajs.
The issue persists if lib is requiring another library (e.g. cheerio) that imports a json file. Same as above, if cheerio is included in app instead, it works fine.
If you don't know lernajs, it's a tool to manage monorepos and it's basically symlinking the lib package into ./app/node_modules/.
The issue was resolved by adding json-loader to the project's root directory package.json!

Categories

Resources