Format argument value before passing to a yarn/npm script - javascript

I have a storybook start script which I want to run for some specific folder:
"storybook": "start-storybook -p 6006 -s ./src"
This loads all stories from src folder. As the amount of stories becomes larger, I want to run stories only from some of subfolders:
start-storybook -p 6006 -s ./src/components/CommonComponents
start-storybook -p 6006 -s ./src/components/DashboardComponents
How can I format argument value dynamically in order to start storybook like this below?
$ yarn storybook CommonComponents
And it would turn into:
start-storybook -p 6006 -s ./src/components/CommonComponents

storybook task could be a script, and then inside the script you parse the arguments, and call start-storybook
Create a task in package.json (e.q run-storybook) and set it to execute the custom script:
"run-storybook": yarn ./path/to/script.js
#!/bin/env node
// script.js
const { spawn } = require('child_process')
const args = process.argv.slice(2)
const port = args[1]
const component = args[3]
const path = `./src/components/${component}`
spawn('yarn', ['start-storybook', '-p', port, '-s', path], {
stdio: 'inherit',
shell: true
})
Then you can call: yarn run-storybook -p 600 -s yourcomponent
Note: make sure the script is executable: chmod +x /path/to/script.js.

Related

force regeneration of code in vue 3 when not using single file components

I'm using vue 3 with jest for unit tests. My component is in the .vue file, with js and css in separate files and included in the .vue via src=:
<template>
<div>my library</div>
</template>
<script src="./library.js"></script>
<style src="./library.css"></style>
This works well for the most part, e.g. npm run serve reloads and refreshes everything as I save changes to those files.
However, when I run npm run test:unit the tests are running against a stale (cached?) version of my library.js. My package.json includes in scripts: "test:unit": "vue-cli-service test:unit",. I suspect it is cached because if I add a comment to the .vue file, it runs against the correct version of the .js, but if I remove the comment (so the file matches the previous version) then it runs against the stale .js again.
Possibly interesting is that running vue-cli-service test:unit --watch does re-run the tests when I change the .js file, but it runs against the stale version and not the new version that triggers the re-run.
The only workaround I seem to have is to append to a dummy comment in the .vue file, which is annoying. Or move to SFC which I find annoying because editor support for the different sections isn't as good as it is with separate files.
How can I get npm / vue-cli-service to bypass this apparent caching? Or is there a way to clear the cache?
The script below will reproduce the issue. Note in the output at the bottom that the tests are run three times:
On the first run the output should include "hello created 1".
Then the .js file is edited to change that string so that on the second run the output should be "hello created 2". However, when I run this script it provides "hello created 1" on both test runs.
Then the .vue file is edited to change a dummy comment. On the third run, the output is "hello created 2" as expected.
#!/bin/bash
if [[ -f package.json ]]
then
echo "'cd ..' and rerun this script"
echo "you need to be in the parent directory to the project directory"
exit 1
fi
if [[ ! -d utfail ]]
then
vue create -p __default_vue_3__ utfail
cd utfail
# specific versions are based on what I was using originally
npm install vue#3.0.3
npm install -D #vue/test-utils#2.0.0-beta.11
npm install -D #vue/compiler-sfc#3.0.3
npm install -D vue-jest#5.0.0-alpha.7
npm install -D #vue/cli-plugin-unit-jest#4.5.9
npm install -D typescript#3.9.7
else
cd utfail
fi
# hack: replace the default lint script with test:unit
sed -i -e 's/^.*"lint":.*$/ "test:unit": "vue-cli-service test:unit"/' package.json
cat <<EOF > jest.config.js
module.exports = {
moduleFileExtensions: ["js", "json", "vue"],
preset: '#vue/cli-plugin-unit-jest',
transform: {
'^.+\\.js$': "babel-jest",
'^.+\\.vue$': 'vue-jest'
},
"automock": false,
"setupFiles": [
"./setupJest.js"
]
}
EOF
cat <<EOF > src/components/HelloWorld.vue
<!-- dummy comment 1 -->
<template>
<div class="hello">blah</div>
</template>
<script src="./helloworld.js"></script>
<style></style>
EOF
cat <<EOF > src/components/helloworld.js
export default {
name: 'HelloWorld',
created() {
console.log("hello created 1")
}
}
EOF
cat <<EOF > setupJest.js
// require('jest-fetch-mock').enableMocks()
EOF
mkdir -p __tests__
cat <<EOF > __tests__/app.spec.js
import { mount } from '#vue/test-utils'
import App from './../src/App.vue'
import HelloWorld from './../src/components/HelloWorld.vue'
describe('HelloWorld', () => {
beforeEach(() => {
})
it('exists', () => {
const wrapper = mount(HelloWorld)
expect(wrapper.exists()).toBe(true)
})
})
EOF
printf '\n*\n*\n*\n*** about to run tests (round 1)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit
sed -i -e '/hello created/s/1/2/' src/components/helloworld.js
printf '\n*\n*\n*\n*** about to run tests (round 2)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit
sed -i -e '/dummy comment/s/1/2/' src/components/HelloWorld.vue
printf '\n*\n*\n*\n*** about to run tests (round 3)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit
Configure Jest to disable the test cache:
// jest.config.js
module.exports = {
cache: false,
}
Or add the --no-cache flag to the test:unit npm script:
// package.json
{
"scripts": {
"test:unit": "vue-cli-service test:unit --no-cache"
}
}
Or clear the cache with this command from the project's root directory:
npx jest --clearCache

Argument passing to PM2

I want to put in production a node service :
When I launch my application with my arguments like that : node ./backend -c "uf4m6fhnh" -s "SPNLGZsUoSpQ=" -o "8696". Everything works well.
Now I want to put it in production with PM2 :
I have tried the 2 ways to to that (CLI and JSON file) like that :
CLI version :
pm2 start backend.js --node-args="-c uf4lvm6fhnh -s SPNLGZsUoSpQ= -o 8696" --name MyAppName
and also :
pm2 start backend.js --name MyAppName -- "-c uf4lvm6fhnh -s SPNLGZsUoSpQ= -o 8696"
Config file (JSON) :
{
"apps": [
{
"name": "MyAppName ",
"script": "./backend.js",
"node_args": [
"-c",
"uf4lvm6fhnh",
"-s",
"SPNLGZsUoSpQ=",
"-o",
"8696"
]
}
]
}
and then : pm2 start myConfigJson.json
For each of this possible solution, I have the same error in my pm2 logs :
Error: Cannot find module '/home/me/Projects/Project/uf4lvm6fhnh'
(Note that the not found module is my passed argument)
Any ideas ?
Use args instead.
node_args is an alias to interpreter_args which passes arguments to node itself, rather than the script. As a result, your command line ends up calling -c|--check on node itself instead.
See http://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/#programmatic-api and https://nodejs.org/api/cli.html#cli_c_check

Gulp build task failing inside docker

I have a simple Hapi.js Node API. Since I have used TypeScript to write the API, I wrote Gulp task for transpiling the code. My API works fine if I run it directly in my main machine but I get the following error when I try to run it inside Docker:
Error:
Docker compose command:
docker-compose -f docker-compose.dev.yml up -d --build
Here is my code:
./gulpfile:
'use strict';
const gulp = require('gulp');
const rimraf = require('gulp-rimraf');
const tslint = require('gulp-tslint');
const mocha = require('gulp-mocha');
const shell = require('gulp-shell');
const env = require('gulp-env');
/**
* Remove build directory.
*/
gulp.task('clean', function () {
return gulp.src(outDir, { read: false })
.pipe(rimraf());
});
/**
* Lint all custom TypeScript files.
*/
gulp.task('tslint', () => {
return gulp.src('src/**/*.ts')
.pipe(tslint({
formatter: 'prose'
}))
.pipe(tslint.report());
});
/**
* Compile TypeScript.
*/
function compileTS(args, cb) {
return exec(tscCmd + args, (err, stdout, stderr) => {
console.log(stdout);
if (stderr) {
console.log(stderr);
}
cb(err);
});
}
gulp.task('compile', shell.task([
'npm run tsc',
]))
/**
* Watch for changes in TypeScript
*/
gulp.task('watch', shell.task([
'npm run tsc-watch',
]))
/**
* Copy config files
*/
gulp.task('configs', (cb) => {
return gulp.src("src/configurations/*.json")
.pipe(gulp.dest('./build/src/configurations'));
});
/**
* Build the project.
*/
gulp.task('build', ['tslint', 'compile', 'configs'], () => {
console.log('Building the project ...');
});
/**
* Run tests.
*/
gulp.task('test', ['build'], (cb) => {
const envs = env.set({
NODE_ENV: 'test'
});
gulp.src(['build/test/**/*.js'])
.pipe(envs)
.pipe(mocha({ exit: true }))
.once('error', (error) => {
console.log(error);
process.exit(1);
});
});
gulp.task('default', ['build']);
./.docker/dev.dockerfile:
FROM node:latest
LABEL author="Saurabh Palatkar"
# create a specific user to run this container
# RUN adduser -S -D user-app
# add files to container
ADD . /app
# specify the working directory
WORKDIR app
RUN chmod -R 777 .
RUN npm i gulp --g
# build process
RUN npm install
# RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN npm run build
# RUN npm prune --production
EXPOSE 8080
# run application
CMD ["npm", "start"]
./docker-compose.dev.yml:
version: "3.4"
services:
api:
image: node-api
build:
context: .
dockerfile: .docker/dev.dockerfile
environment:
PORT: 8080
MONGO_URL: mongodb:27017
NODE_ENV: development
ports:
- "8080:8080"
links:
- database
database:
image: mongo:latest
ports:
- "27017:27017"
What I am missing here?
Edit:
The problem wasn't what I initially thought. The order of the operations in the Dockerfile was simply wrong: you have to install the dependencies first, then copy all the files into the container (so the installed dependencies will also be copied), only then you can use the application and its dependencies.
I made a pull request on your repo with those fixes :)
Don't user node latest, configure docker file to the exact node version that you are using in the DEV environment.

Using wildcard to run multiple scripts for npm run test

I my package.json I have
"scripts": {
"test": "node tests/*-test.js"
}
And I have a-test.js and b-test.js in the tests folder, which I can verify by running ls tests/*-test.js.
However, npm run test is only executing a-test.js. How can I execute all *-test.js scripts? Explicitly listing them is not an option, since I will have more than 2 to run in the future.
You could use a task manager such as grunt or gulp, or a simple script that execute those scripts:
test.js:
require('./test/a-test.js')
require('./test/b-test.js')
package.json
"scripts": {
"test": "node test.js"
}
You could also use the include-all module for automating these for you https://www.npmjs.com/package/include-all
Example using includeAll:
const path = require('path');
const includeAll = require('include-all');
const controller = includeAll({
dirname: path.join(__dirname, 'test'),
filter: /(.+test)\.js$/,
});

How to reset -g parameter for "npm install" in hooks scripts?

I have a following project structure:
install.js:
var path = require('path'),
exec = require('child_process').exec;
exec('npm install', {cwd: path.join(__dirname, './some_modules')});
package.json:
"scripts": {
"install": "node install.js"
},
"dependencies": {
"gulp": "3.8.10"
},
And have some dependencies in some_modules/package.json.
In case installation locally we get the expected result:
But in case installation globally (with -g parameter) we have following broken structure:
Question: How to get rid of the influence -g parameter for install.js -> exec('npm install') ?
Try it here: https://github.com/MishaMykhalyuk/npm-i-with-g-and-hooks (npm install -g git+https://github.com/MishaMykhalyuk/npm-i-with-g-and-hooks.git).

Categories

Resources