package.json reference value from external json - reactjs

I have a metadata.json file which includes some values:
{"build":{"major":0,"minor":88}}
In my create-react-app project, I need to run the script to upload sentry map files:
"sentry" : "sentry-cli releases files 0.88 upload-sourcemaps --validate ./build"
where the 0.88 should be pulled from the metadata.json file. I can then run it with:
npm run sentry
How can I pull the value 0.88 from the metadata.json file with build major/ minor and insert it into the sentry command?

I am not sure if there is a solution to do this in package.json itself.
This is how I would have solved this problem:
Create a new js file. Let's say the name is run-command.js.
Add a line node ./run-command.js inside the script object in package.json.
Import the metadata.json file in this newly created file and extract the necessary data
Execute your command
Example:
package.json
scripts: {
"sentry: "node ./run-command.js"
}
run-command.js
const metadata = require('./metadata.json');
const { exec } = require('child_process');
exec(`echo ${metadata.build.major}`, (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
Replace echo with your command. It would look something like ./node_modules/.bin/sentry ...
You can use a bash script like ./sentry.sh if you are comfortable with shell scripts.

Related

How do I exclude files from svelte-kit build?

If I run npm run build with SvelteKit it seems to include all files from the src folder. Is it possible to exclude a certain file type (eg. *test.js)?
Example
Select demo app with npm init svelte#next my-app
Add the following code to src/routes/todos/foo.test.js
describe('foo', () => {
it('temp', () => {
expect(true).toBe(false)
})
})
npm run build
npm run preview
Result: describe is not defined
Workaround
Move tests outside of src
UPDATE: SvelteKit 1.0.0-beta now requires pages/endpoints to follow a specific naming pattern, so explicit file exclusion should no longer be needed.
SvelteKit specially handles files in the routes/ directory with the following filenames (note the leading + in each filename):
+page.svelte
+page.js
+page.server.js
+error.js
+layout.svelte
+layout.js
+layout.server.js
+server.js
All other files are ignored and can be colocated in the routes/ directory.
If, for some reason, you need to have a file that has a special name shown above, it's currently not possible to exclude that file from special processing.
Original outdated answer:
SvelteKit 1.0.0-beta supports a routes configuration that enables file exclusion from the src/routes directory. The config value is a function that receives a file path as an argument, and returns true to use the file as a route.
For example, the following routes config excludes *.test.js files from routes:
// sveltekit.config.js
⋮
const config = {
kit: {
⋮
routes: filepath => {
return ![
// exclude *test.js files
/\.test\.js$/,
// original default config
/(?:(?:^_|\/_)|(?:^\.|\/\.)(?!well-known))/,
].some(regex => regex.test(filepath))
},
},
}
demo

Use a config file in jenkins pipeline

I have a Jenkins pipeline job, which is parametrized. It will take a string input and pass that to a bat script.
Input : https://jazz-test3.com/web/projects/ABC
I wanted to include a config file, it should be placed in a location (may be in the Jenkins machine locally or what can be the best option?).
Sample config file: server_config.txt
test1 : https://jazz-test1.com
test2 : https://jazz-test2.com
test3 : https://jazz-test3.com
Once the user input is received , the job should access this file and check whether the server in the input link is present in the config file.
If present call the bat script if not present throw an error , the server is not supported.
Expected result:
Input 1 : https://jazz-test3.com/web/projects/ABC
Job should run
Input 2 : https://jazz-test4.com/web/projects/ABC
Job should fail with error message
What is the best way of achieving this ?
Can we do it directly from the pipeline or a separate script will be required to perform this ?
Thank you for the help!!
Jenkins supports configuration files stored on the controller via the config-file-provider plugin. See Manage Jenkins | Managed Files for the collection of managed configuration files.
You can add a JSON config file with id "test-servers" that stores your test server configuration:
{
"test1":"https://jazz-test-1.com",
"test2":"https://jazz-test-1.com"
}
Then the job pipeline would do something like:
servers = [:]
stage("Setup") {
steps {
configFileProvider([fileId:'test-servers', variable:'test_servers_json']) {
script {
// Read the json data from the file.
echo "Loading configured servers from file '${test_servers_json}' ..."
servers = readJSON(file:test_servers_json)
}
}
}
}
stage('Test') {
steps {
script {
// Check if 'server' is supported.
if (!servers.containsKey(params.server)) {
error "Unsupported server"
}
build job:'...', parameters:[...]
}
}
}

React - synchronous txt file to string?

I'm absolutely baffled by this one...
In my React project with create-react-app, I have a standalone js file in which I'd like to read a string from a txt file. The txt file is part of a project and not on a server.
I can't seem to find any answers of how to complete this seemingly trivial task in a synchronous manner. These would seem like obvious options:
import text from './data/text.txt';
const text = require('./data/text.txt');
Both lines above return a new path that includes /static/media/, which I can access through localhost in the browser, but that doesn't help me.
I can use JSON but it's almost a matter of principle at this point. It just seems ridiculous that I can't read a simple txt file.
You can use webpack raw-loader to directly import raw files into your project.
Install:
$ npm install raw-loader --save-dev
Config:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.txt$/i,
use: 'raw-loader',
},
],
},
};
Usage:
import text from './data/text.txt';
console.log(text); // This line will print out the content of the text file in the console

Any way to have a common netlify.toml file for a single repository and multiple sites?

I'm looking out a way to define two site builds on netlify, sourced from the same repo, using a single common netlify.toml. Is it possible to do so?
I have a GitHub repository named hugo-dream-plus for which I've configured two website builds on netlify, namely dream-plus-posts and dream-plus-cards. Both of these builds share the same environment variables and mostly all of the configurations, except for the build commands:
hugo --config cards.toml #For dream-plus-cards
hugo --config posts.toml #For dream-plus-posts
I was wondering if there was a way for me to create a common netlify.toml file, since the repo is the same for both builds, for both these sites.
I've already used the web UI for configuring each build separately, but it's quite bothersome to modify each of them, that's why I'm preferring the above scenario.
What I plan to do is to have all configurations shared between the two builds except for the build command, which would be defined separately as shown above.
As of the date of this answer, Netlify does not support a way to change values in the netlify.toml, because it is read in prior to your build. Except for the headers and redirects, which allow you to change at build.
Using Environment Variables directly as values ($VARIABLENAME) in your netlify.toml file is not supported.
However
You could run a script command and have it changed based on the domain or an environment variable. There are a few setups that would work.
Here is how I might accomplish what you want based on the domain name.
netlify.toml
[build]
command = "node ./scripts/custom.js"
publish = "public"
scripts/custom.js
const exec = require('child_process').exec;
const site = process.env.URL || "https://example.com";
const domain = site.split('/')[site.split('/').length - 1];
let buildCommand;
switch(domain) {
case "dream-plus-posts.netlify.com":
buildCommand = 'hugo --config posts.toml';
break;
case "dream-plus-cards.netlify.com":
buildCommand = 'hugo --config cards.toml';
break;
default:
throw `Domain ${domain} is invalid`;
}
async function execute(command){
return await exec(command, function(error, stdout, stderr){
if (error) {
throw error;
}
console.log(`site: ${site}`);
console.log(`domain: ${domain}`);
console.log(stdout);
});
};
execute(buildCommand);
Things to note:
I did not test the stdout to the log using this method with Hugo. The child process captures the output and returns it in stdout.
We don't want to capture errors, because we want our build to fail on errors so this will cause an exit code other than 0
You can inline other commands with this solution (i.e. "node ./scripts/custom.js && some other command before deploy")
You could also just check an environment variable you set rather than domain name

How to add sourcemap in React Native for Production?

I received error log like the following while the app crashed:
Fatal Exception: com.facebook.react.modules.core.JavascriptException:
onSelect index.android.bundle:20:7148 onPress
index.android.bundle:20:2435
But it's not really helpful for me to trouble shoot. How could I enable source map so that I could track down where the issue is ?
UPDATE 2018
https://docs.expo.io/versions/latest/guides/using-sentry.html Looks promising !
For source mapping here is the way I go about it:
In my bundle command for my production build I tell it to generate a source map:
iOS:
react-native bundle --platform ios --entry-file index.ios.js --dev false --bundle-output ./ios/main.jsbundle --assets-dest ./ios --sourcemap-output ./sourcemap.js
Android - I had to actually modify the android/app/react.gradle file to get source maps generating on release compile. There might be an easier way but basically you find where it builds up the bundle command in the bundleReleaseJsAndAssets method and add the source map bit to it:
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine "cmd","/c", "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease, "--sourcemap-output", file("$buildDir/../../../sourcemap.js")
} else {
commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease, "--sourcemap-output", file("$buildDir/../../../sourcemap.js")
}
The output path looks a bit odd but that puts it at your root level (same spot as iOS. I wanted it that way. You can obviously put it anywhere).
Then once you have an error with the line number that means nothing you run it through the "source-map" NPM package. You could probably get very elaborate with your approach but I simply went with:
var sourceMap = require('source-map');
var fs = require('fs');
fs.readFile('./sourcemap.js', 'utf8', function (err, data) {
var smc = new sourceMap.SourceMapConsumer(data);
console.log(smc.originalPositionFor({
line: 16,
column: 29356
}));
});
Where line and column should be replaced withe line and column number from your example output above.
This obviously works best if you have the source maps stored somewhere as the line and column numbers change from build to build as your code changes. It should get pretty close though if you can use you source control setup of choice to go back to the commit that was used to build the app in question and re-generate the bundle with the additional bits to the command to generate the source map.
Android inspired by #chetstone's answer
Starting on v0.32 for android, you can modify your android/app/build.gradle to accomplish this.
Look for the line
apply from: "../../node_modules/react-native/react.gradle"
Just above this, you will see something like:
project.ext.react = [
entryFile: "index.js",
]
Modify it to match the following
project.ext.react = [
entryFile: "index.js",
extraPackagerArgs: ["--sourcemap-output", file("$buildDir/../../../sourcemap.android.js")]
]
On iOS
Go to your build phases in Xcode for the "Bundle React Native code and images" phase and add:
export EXTRA_PACKAGER_ARGS="--sourcemap-output sourcemap.ios.js"
As noted, there's no obvious way to generate the sourcemap file for React Native on iOS. The bundle command is called from react-native-xcode.sh, and there's no provision to add parameters to the bundle command line. But I found a clean way to do it.
react-native-xcode.sh uses the environment variable BUNDLE_CONFIG to specify a config file. If you create an empty config file it has no effect, and then you can add additional CLI parameters.
Create an empty config file.
touch null_config
Set BUNDLE_CONFIG with your config file, and piggyback the --sourcemap-output parameter.
export BUNDLE_CONFIG="null_config --sourcemap-output ./sourcemap.js.map"
When you build, the file sourcemap.js.map will be created.
This is only for iOS.
step 1: Generate sourcemap.js file by using following command.
add this line in package.json file
"bundle:ios": "mkdir -p ios/{Bundle,source-map}; react-native bundle --platform ios --entry-file index.js --dev false --bundle-output ios/Bundle/main.jsbundle --assets-dest ios/Bundle --sourcemap-output ios/source-map/sourcemap.js"
Run this command, it will create sourcemap.js file under $PROJECT_DIR/ios/source-map/ folder
$ yarn bundle:ios
Step 2: Create a file sourcemap-decoder.js under $PROJECT_DIR/ios/source-map/
$ cd ios/source-map/
$ touch sourcemap-decoder.js
Content of sourcemap-decoder.js is
const sourceMap = require('source-map'); //(install- npm i source-map)
const fs = require('fs');
const path = require('path');
fs.readFile(path.resolve(__dirname, 'sourcemap.js'), 'utf8', async (err, data) => {
if (err) {
console.log('err', err,);
}
const consumer = await new sourceMap.SourceMapConsumer(JSON.parse(data));
console.log(consumer.originalPositionFor({
line: 1408,
column: 7762
}));
});
Step 3: execute the script for decoding
$ node ios/source-map/sourcemap-decoder.js

Resources