YEOMAN run multiple sub generators in one function - yeoman

I have an angular based generator with three sub generators for controller directive and service. I want to run one function that takes the NAME variable/input and runs all three of these at the same time instead of having to run each one separately.

Yeoman offers composeWith() (docs) which you can use to invoke other (sub)generators.
'use strict';
var generators = require('yeoman-generator');
module.exports = generators.Base.extend({
constructor: function () {
generators.Base.apply(this, arguments);
this.argument('theName', {
type: String,
required: true
});
},
initializing: function() {
this.composeWith('my-generator:mysubgen1', { args: [this.theName] });
this.composeWith('my-generator:mysubgen2', { args: [this.theName] });
}
});
In the example above I assume your generator is named my-generator and has two subgenerators (mysubgen1 and mysubgen2).
The code above would go into a third subgenerator, e.g. doall. If you call $ yo my-generator:doall foobar it would now run both of the composed sub-generators, passing foobar as first argument.

Related

Nuxt 3 environment variables for static site [duplicate]

I have .env file in the project root, and in my nuxt config I am using variables to configure ReCaptcha like this:
import dotenv from 'dotenv'
dotenv.config()
export default {
modules: [
['#nuxtjs/recaptcha', {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}],
]
}
and in .env like this:
RECAPTCHA_SITE_KEY=6L....
but the application always failed with console log error:
ReCaptcha error: No key provided
When I hard-code ReCaptcha key directly like that: siteKey: 6L.... app start working, so I guess the problem is with reading .env props in nuxt.config
do you have any idea how to fix it?
EDIT:
I tried update my nuxt.config by #kissu recommendation and by example which I found here: https://www.npmjs.com/package/#nuxtjs/recaptcha
so there is new nuxt.config which also not working:
export default {
modules: [
'#nuxtjs/recaptcha',
],
publicRuntimeConfig: {
recaptcha: {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}
}
}
If your Nuxt version is 2.13 or above, you don't need to use #nuxtjs/dotenv or anything alike because it is already backed into the framework.
To use some variables, you need to have an .env file at the root of your project. This one should be ignored by git. You can then input some keys there like
PUBLIC_VARIABLE="https://my-cool-website.com"
PRIVATE_TOKEN="1234qwer"
In your nuxt.config.js, you have to input those into 2 objects, depending of your use case, either publicRuntimeConfig or privateRuntimeConfig:
export default {
publicRuntimeConfig: {
myPublicVariable: process.env.PUBLIC_VARIABLE,
},
privateRuntimeConfig: {
myPrivateToken: process.env.PRIVATE_TOKEN
}
}
Differences: publicRuntimeConfig can basically be used anywhere, while privateRuntimeConfig can only be used during SSR (a key can only stay private if not shipped to the browser).
A popular use case for the privateRuntimeConfig is to use it for nuxtServerInit or during the build process (either yarn build or yarn generate) to populate the app with headless CMS' API calls.
More info can be found on this blog post: https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config/
Then, you will be able to access it into any .vue file directly with
this.$config.myPublicVariable
You access it into Nuxt's /plugins too, with this syntax
export default ({ $axios, $config: { myPublicVariable } }) => {
$axios.defaults.baseURL = myPublicVariable
}
If you need this variable for a Nuxt module or in any key in your nuxt.config.js file, write it directly with
process.env.PRIVATE_TOKEN
Sometimes, the syntax may differ a bit, in this case refer to your Nuxt module documentation.
// for #nuxtjs/gtm
publicRuntimeConfig: {
gtm: {
id: process.env.GOOGLE_TAG_MANAGER_ID
}
},
PS: if you do use target: server (default value), you can yarn build and yarn start to deploy your app to production. Then, change any environment variables that you'd like and yarn start again. There will be no need for a rebuild. Hence the name RuntimeConfig!
Nuxt3 update
As mentioned here and in the docs, you can use the following for Nuxt3
nuxt.config.js
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
runtimeConfig: {
public: {
secret: process.env.SECRET,
}
}
}
In any component
<script setup lang="ts">
const config = useRuntimeConfig()
config.secret
</script>
In a composable like /composables/test.js as shown in this comment
export default () => {
const config = useRuntimeConfig()
console.log(config.secret)
}
Here is the official doc for that part.
You can also use the env property with Nuxt
nuxt.config.js:
export default {
// Environment variables
env: {
myVariable: process.env.NUXT_ENV_MY_VAR
},
...
}
Then in your plugin:
const myVar = process.env.myVariable
It's very easy. Providing you an example with axios/nuxt
Define your variable in the .env file:
baseUrl=http://localhost:1337
Add the variable in the nuxt.config.js in an env-object (and use it in the axios config):
export default {env: {baseUrl: process.env.baseUrl},axios: {baseURL: process.env.baseUrl},}
Use the env variable in any file like so:
console.log(process.env.baseUrl)
Note that console.log(process.env) will output {} but console.log(process.env.baseUrl) will still output your value!
For nuxt3 rc11, in nuxt.conf.ts file:
export default defineNuxtConfig({
runtimeConfig: {
public: {
locale: {
defaultLocale: process.env.NUXT_I18N_LOCALE,
fallbackLocale: process.env.NUXT_I18N_FALLBACK_LOCALE,
}
}
},
...
and in .env file:
NUXT_I18N_LOCALE=tr
NUXT_I18N_FALLBACK_LOCALE=en
public: is very important otherwise it cannot read it and gives undefined error.
For v3 there is a precise description in the official docs
You define a runtimeConfig entry in your nuxt.config.[ts,js] which works as initial / default value:
export default defineNuxtConfig({
runtimeConfig: {
recaptchaSiteKey: 'default value' // This key is "private" and will only be available within server-side
}
}
You can also use env vars to init the runtimeConfig but its written static after build.
But you can override the value at runtime by using the following env var:
NUXT_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
If you need to use the config on client-side, you need to use the public property.
export default defineNuxtConfig({
runtimeConfig: {
public: {
recaptchaSiteKey: 'default value' // will be also exposed to the client-side
}
}
}
Notice the PUBLIC part in the env var:
NUXT_PUBLIC_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
This is very strange because we can't access process.env in Nuxt 3
In the Nuxt 3, we are invited to use the runtime config, but this is not always convenient, because the Nuxt application context is required.
But in a situation where we have some plain library, and we don’t want to wrap it in plugins nor composables functions, declaring global variables through vite / webpack is best:
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
define: {
MY_API_URL: JSON.stringify(process.env.MY_API_URL)
}
}
})
And then you can use in any file without dancing with a tambourine:
// some-file.ts
console.log('global var:', MY_API_URL) // replaced by vite/webpack in real value

Electron: accessing the browser window of the single instance when called a second time

I have been able to successfully create an Electron app that links to the web app (using window.loadUrl).
I have been able to pass some command line params to the web app using window.webContents.send .... On the web app, the javascript receives the parameter and updates the screen.
I am using (2) by opening a file (right-click on it from the directory) through file association using process.argv[1]. This too works.
What I would like is that if I right-click on a second file, it must be passed on to the same electron instance. I am having some issues for this.
I have used the recommended approach for preventing multiple instances as below:
...
let myWindow = null
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
// I do not want to quit
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
...
}
In the above logic, when the program is unable to get-the-lock, the boiler-plate code quits. That works fine, in the sense, that a second window does not open. But in my case, I would like to use the process.argv[1] of the second request and pass it to the web program of the existing instance.
I have not been successful in getting a handle to the browserWindow of the other instance. I would not want to work on multiple windows where each window would call another load of the web app. The current webapp has the ability to update multiple tabs in the same window based on different parameters. Basically, that is handled in the web app itself.
What could be the solution? Thanks
I got it working. It starred at my face and I did not see it. Added a few logs and it helped. Something like this would be a solution.
...
let myWindow = null;
...
function createWindow() {
....
return win;
}
function processParams(...) {
...
}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
//.. this is called the second time
// process any commandLine params
processParams(...)
...
});
app.on('whenReady')
.then(_ => {
myWindow = createWindow();
// this is called the first time
// process any argv params
processParms(...);
});
}

How to run two separate plugins in parallel in a Gulp pipe?

I'm trying to setup a Gulp task to convert .ttf fonts to webfont formats, by using gulp-ttf2woff and gulp-ttf2woff2 plugins. The respectively convert the source fonts to .woff and .woff2.
I've come out with these two separate functions, one for each plugin:
function fontsW(done) {
src(fontsSrc)
.pipe(ttf2woff())
.pipe(dest(fontsDist))
done();
};
function fontsW2(done) {
src(fontsSrc)
.pipe(ttf2woff2())
.pipe(dest(fontsDist))
done();
};
Is it possible to condensate them in a single function, let's call it function fonts(done) {} that takes care of both plugins at once?
Basically, I'd like to have something like this
function fontsW2(done) {
src(fontsSrc)
.pipe(ttf2woff())
.pipe(ttf2woff2())
.pipe(dest(fontsDist))
done();
};
where both ttf2woff() and ttf2woff2() receive the output of src and give their own processed files to dest.
You can do this:
function fontsW(done) {
src(fontsSrc)
.pipe(ttf2woff())
.pipe(dest(fontsDist))
src(fontsSrc)
.pipe(ttf2woff2())
.pipe(dest(fontsDist))
done();
};
You can define a task that calls both functions in parallel:
gulp.task('fonts', gulp.parallel(ttf2woff, ttf2woff2));
You can either use this task in other tasks (e.g. call it from your default task), or you can call it directly from terminal:
gulp fonts

Is there a module Run Block equivalent in AngularDart?

I am looking for a way in dart to do the following in AngularJS:
angular.module('myModule', []).
run(function(injectables) { // instance-injector
// This is an example of a run block.
// You can have as many of these as you want.
// You can only inject instances (not Providers)
// into run blocks
});

Jasmine Headless Webkit backbone and Handlebars

I am using the sht_rails gem to render handlebars templates in my Rails 3.2/Backbone App.
I'm hoping to use this .handlebars template in both the backbone and rails portion of the app, but so far I just have it working in the backbone.
I'm using it like so:
class MyApp.views.MyView extends MyApp.views.BaseView
template: SHT['templates/feed_item']
render: ->
data = {}
#$el.html #template(data)
#
This works great in app, no problems at all, my handlebars template is looking sweet.
However, this is no good for my js testing (I'm using Jasmine with jasmine-headless-webkit)
This is what happens:
$ jasmine-headless-webkit
ReferenceError: Can't find variable: SHT
This makes total sense, as it seems that the sht_rails gem registers the SHT variable, however, it doesn't seem to do this in when I test.
Is there a good way to register the SHT variable when running jhw? or jasmine by itself? I don't even need the template to render for my test, just knowing that the template is called would be enough for me. But for now, all my jasmine tests are broken until I figure out how to register this SHT.
Thanks!
We faced the same problem when using jade templates in our Rails 3.2/Backbone/Marionette app via the tilt-jade gem (hence the JST variable in the code samples below). Our solution was to create a template abstraction and then use Jasmine spies to fake a response during spec execution. This approach also allows us to test template usage, construction, etc.
Spies In General
In case you're unfamiliar with Jasmine spies:
Jasmine integrates 'spies' that permit many spying, mocking, and faking behaviors. A 'spy' replaces the function it is spying on.
Abstraction
Create the abstraction:
YourApp.tpl = function(key, data) {
var path = "templates";
path += key.charAt(0) === "/" ? key : "/" + key;
var templateFn = JST[path];
if(!templateFn) {
throw new Error('Template "' + path + '" not found');
}
if(typeof templateFn !== "function") {
throw new Error('Template "' + path + '" was a ' + typeof(templateFn) + '. Type "function" expected');
}
return templateFn(data);
};
and the requisite monkeypatch:
// MONKEYPATCH - Overriding Renderer to use YourApp template function
Marionette.Renderer = {
render: function(template, model){
return YourApp.tpl(template, model);
}
};
Template Abstraction Spy (spec_helper.js)
Now we can spy as follows:
spyOn(YourApp, 'tpl').andCallFake(function(key, data) {
return function() {
return key;
};
});
Bonus
Since we are spying on the YourApp.tpl function, we can also test against it:
expect(YourApp.tpl).toHaveBeenCalledWith("your_template", { model: model, property: value });
Addendum
If you don't already know about the jasmine-headless-webkit --runner-out flag and are debugging your Jasmine specs in the wilderness, check out this post to see how to generate a runner output report with a full backtrace for any failures.

Resources