Exclude a specific package from react metro bundler when building - node.js

I have a library that requires:
rnkata.js when running in react native
webkata.js when running in a browser
nodekata.js when running in node
This hack works OK as long as I'm only targeting node/web:
if (getEnv() == "node") {
eval('require')('nodekata')
} else {
require('webkata')
}
But once I started targeting mobile, metro bundler would complain "webkata not available":
if (getEnv() == "node") {
eval('require')('nodekata')
} else if (getEnv() == "mobile") {
require('rnkata')
} else {
require('webkata')
}
Obviously, I can't use the same eval hack - or I break either webpack or RN. Is there some documentation on how to manage this situation? IE: how can i suppress bundling or interpreting of a 'require' call by platform.
Is there a "suppress by module name" feature? Or some other way to have a platform-specific module?

Metro recently added support for Optional imports. It should be available in React Native v0.63.0. See this issue and this PR for more details.
You could also consider doing naming the files to show which platforms they support. For example:
index.js - web version
index.native.js - android & ios only version
index.android.js - android version
index.ios.js - ios version

Related

How to alert user he/she does not have the correct Nodejs engine when running my app?

I'm developing and application with Node >=14
I'd like that the application wont start or at least provide a warning message:
if the nodejs engine installed on the host environment is not matching the required version.
I know I can possibly achieve it via code, at bootstrap.
I wonder if using the package json engines directive it is possible to obtain this result
...
"engines": {
"node": "^14"
},
...
Actually the above is not considered if I switch on my host for example to node 12
And if I run
npm run start
it will work without providing any feedback or error.
To emulate different nodejs engine version I'm using n package
node/12.18.3
node/13.1.0
node/14.17.0
ο node/14.18.0
Is it possible or the engines directive is going to be fired only on node modules install to check intra package dependencies?
If setting the Node version in package.json file doesn't work then I think you've to alert the user manually.
You can get the current node version from the process.version property.
So you'd have to do something like this:
const currentMajorVersion = +process.version.slice(1).split(".")[0];
// e.g., "v14.10.1" => 14
if(currentMajorVersion < whatever)
console.log("Warning...")

Nodejs - small Express server + trayicon + pkg

I'm trying to find out if smaller file size is possible, to have distributable one file for Express based API server app with some trayicon for basic controls - basically exit + restart app + open the API in default browser.
With Electron Builder I can do --ia32 target in about 68MB, but wonder if any lower size is possible, to learn more about it. But was having problem trying to get Systray2 and related solutions working using pkg (getting ENONENT on the exe file from node_modules (yes, tried adding it to package.json pkg assets, or even copied that exe to traybin folder under project root). I am sure there is a way but I may be missing something maybe obvious, so ready made Git would be great.
So if anything handy possible, is there some boilerplate ready to download? It just feels like waste of space to download Electron, when I only use the builder, Tray & Notification, but no mainWindow, ipc Renderer etc...
Not sure if this is relevant for you still, but I actually ran across the exact same requirement today. After many trials & errors, I did manage to solve it simply by setting the copyDir flag to true as shown in the below code when using the systray2 npm package:
const systray = new SysTray({
menu: {
icon: os.platform() === 'win32' ? './logo_s.ico' : './logo_s.png',
isTemplateIcon: os.platform() === 'darwin',
title: 'App',
tooltip: 'App',
items: [
itemExit
]
},
debug: false,
copyDir: true // This makes the systray2 work with pkg
})
My win-x64 binary size ended up at 38MB with Brotli compression (fastify server + systray2 + some css/images/js).
I didn't compare it with Electron Builder though, but I have a hunch it would be larger than that :)

ParserError while compiling solidity code

I am new to solidity.
This is my 1st simple project
when I do node compile.js & I am getting following error:
My Error :
{
contracts: {},
errors: [
":7:16: ParserError: Expected identifier, got 'LParen'\n" +
' constructor(string initialMessage) public{\r\n' +
' ^\n'
],
sourceList: [ '' ],
sources: {}
}
my compile.js
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const inboxPath = path.resolve(__dirname,'contracts','Inbox.sol');
const source = fs.readFileSync(inboxPath,'utf8');
console.log(solc.compile(source,1));
my Inbox.sol
pragma solidity ^0.4.17;
contract Inbox {
string public message;
constructor(string initialMessage) public{
message = initialMessage;
}
function setMessage(string newMessage) public{
message = newMessage;
}
}
I'm not sure why you are attempting to compile your smart contract natively using node. That is a fairly cumbersome approach (although it can be done, albeit with exponentially more work on your part), especially when tools already exist for this purpose.
The prefered method would be to use a tool such as the most recent build of truffle (which is a CLI tool available as a NodeJS package via NPM for compiling, deploying and testing smart contracts), instead of using NodeJS to compile.
Simply install truffle as a global package from a console using:
npm install -g truffle
Then navigate to your project root directory and run:
truffle init
This will generate a barebone project structure with everything that is required (such as directories for contracts and migrations).
After the project has been init'ed, open the truffle-config.js file and add the configurations required for your project:
module.exports = {
networks: {
//Configuration for localhost private dev network for testing code
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" //Match any network id
}
//Connecting to the main, live ethereum network requires different config
//and should NOT be used for development purposes.
//Only after your contracts have been thoroughly tested and audited should you deploy a production ready project to the main net.
},
compilers: {
solc: {
version: "0.6.2"
}
}
};
You can specify whichever compiler version suites your needs, however, most contracts now a days should target version 0.6.0 and up for the most recent features.
Learn more about customizing Truffle's configuration here!
Now, this allows you to specify both the network to deploy to and the specific solidity compiler (which truffle will automatically download the correct version if it does not already exist on your system) to run when compiling your project.
After this is complete, your contracts can be compiled easily using:
truffle compile --all --network development
Note that the argument for --network must match an entry in truffle-config.js's networks object (although just for compiling, it should not be necessary to specify a network, only for deployment).
Then there you go! You have compiled your first smart contract.
However, there is one caveat.
At this point you do not have a local test network to deploy to.
When deploying the contract, it's important to be aware to not deploy untested code to the live main network until it has been tested and audited.
Since any changes to the blockchain are permanent, deploying buggy contracts to the live blockchain can't be undone and any bugs can and will be exploited by malicious agents indefinitely.
To solve this issue, the trufflesuite team also provides ganache-cli (alongside various other helpful tools) for running a private test network on localhost. This package is also available via NPM however, that goes beyond the scope of this answer and your question.
Hope that helps you get started, best of luck!
The problem you are facing is a result of the compiler version. with solidity compiler version 0.4.17 all you need to do is replace the constructor keyword with the name of the contract i.e implicitly creating the constructor function. That should do the trick and yes your code editor will most likely complain especially if you have linting enabled but your codes will still run

Angular 6 :: Cannot find name 'require'

My project is created using angular cli [ version - 6.1.3 ].
I installed npm module - is-reachable and used it in my code as -
const isReachable = require('is-reachable');
appDetailsFromJson.forEach(app => {
isReachable(app.server).then(reachable => {
console.log('Hey --> ',reachable);
//=> true
});
However, on running the project it throws the exception - error TS2304: Cannot find name 'require'.
What is the root cause for this & what is the correct way to import a library in angular 6 ?
From the NPM page of isReachable it says (my emphasis):
Works in Node.js and the browser (with browserify).
This means that it is unlikely to work natively in an Angular application as the Angular CLI uses webpack and the standard typescript compiler (rather than browserify) to resolve imports and package dependencies.
In general, imports in Angular are standard ES6-style 'import' statements, e.g.:
import { isReachable } from 'is-reachable';
... or ...
import * as isReachable from 'is-reachable';
If is-reachable itself does not use any further require() statements, this may work, but if it uses require within its own code to bring in its dependencies, you would be in for a lot of difficulty in getting it to work at all - and it would almost certainly be better to find a different way to meet your requirement.

Deploying angular 2 app Aot with Rollup and external dependencies

I've implemented an angular 2 app which utilize Kendo UI Grid:
I am stuck when deploying app with AoT + Rollup:
Error: 'GridModule' is not exported by node_modules\#progress\kendo-angular-grid\dist\npm\js\main.js (imported by app\app.module.js).
Tried this from Rollup documentation but I don't understand how to configure namedExports:
commonjs({
namedExports: {
'node_modules/#progress/kendo-angular-grid/dist/npm/js/main.js': [ 'GridModule' ]
}
});
Using above configuration doesn't solve the problem.
EDIT:
finally my working configuration for grid is:
namedExports: {
'#progress/kendo-angular-grid': ['GridModule'],
'#progress/kendo-angular-intl/dist/npm/js/intl.service': ['IntlService'],
'#progress/kendo-angular-intl/dist/npm/js/cldr-intl.service': ['CldrIntlService'],
'#progress/kendo-angular-grid/dist/npm/js/grid.module': ['GridModule'],
'#progress/kendo-angular-grid/dist/npm/js/shared.module': ['SharedModule'],
'#progress/kendo-angular-grid/dist/npm/js/grid.component': ['GridComponent', 'DEFAULT_SCROLLER_FACTORY'],
'#progress/kendo-angular-grid/dist/npm/js/browser-support.service': ['BrowserSupportService'],
'#progress/kendo-angular-grid/dist/npm/js/selection.service': ['SelectionService'],
'#progress/kendo-angular-grid/dist/npm/js/details.service': ['DetailsService'],
'#progress/kendo-angular-grid/dist/npm/js/column.component': ['ColumnComponent'],
'#progress/kendo-angular-grid/dist/npm/js/header-template.directive': ['HeaderTemplateDirective'],
'#progress/kendo-angular-grid/dist/npm/js/col-group.component': ['ColGroupComponent'],
'#progress/kendo-angular-grid/dist/npm/js/cell-template.directive': ['CellTemplateDirective'],
'#progress/kendo-angular-grid/dist/npm/js/header.component': ['HeaderComponent'],
'#progress/kendo-angular-grid/dist/npm/js/resizable.directive': ['ResizableContainerDirective'],
'#progress/kendo-angular-grid/dist/npm/js/list.component': ['ListComponent'],
'#progress/kendo-angular-grid/dist/npm/js/pager.component.js': ['PagerComponent'],
'#progress/kendo-angular-grid/dist/npm/js/template-context.directive': ['TemplateContextDirective'],
'#progress/kendo-angular-grid/dist/npm/js/footer.component': ['FooterComponent'],
'#progress/kendo-angular-grid/dist/npm/js/selectable.directive': ['SelectableDirective'],
'#progress/kendo-angular-grid/dist/npm/js/table-body.component': ['TableBodyComponent'],
'#progress/kendo-angular-grid/dist/npm/js/field-accessor.pipe': ['FieldAccessorPipe'],
'#progress/kendo-angular-grid/dist/npm/js/list.component': ['ListComponent', 'SCROLLER_FACTORY_TOKEN','DEFAULT_SCROLLER_FACTORY']
}
It doesn't work if 'include' section is enabled
Update (Dec 7, 2016): All packages are updated to export ES2015 module bundles, so integration with Rollup should work out of the box.
Nov 7, 2016: At the time of writing, the NPM packages of Kendo UI for Angular do not provide module entry points (that use imports/export), which are required for Rollup to work automatically. We plan on introducing them in the future; until they are in place, this problem can be resolved via namedExports.
See the related GitHub issue

Resources