How to expose package.json in angular app - javascript

I'm running my app with ng serve and am wondering if there is a way to fetch the package.json file inside my app.
My initial idea was to copy package.json to the folder ./dist and read it from there but this seems to not be an option when using ng serve, which works in-memory and doesn't use the dist folder.
Is there a way to get the file when using ng serve or alternatively to make ng serve use the dist older instead of running in in-memory mode?
I am using Angular 4 and angular CLI version 1.3.2 (together with npm 4.3.0).
Thanks!

What build mechanism are you using? If you're in something like webpack, with the appropriate loader you can do
import package from '../package.json'; //es6, or
var package = require('../package.json'); //commonJS
console.log( package.version );
This will bundle up the package.json file as part of your build step. This can also be done using Browserify (but you'll probably need a transform).

I was able to solve it by setting the glob property in the project assets configuration inside .angular-cli.json
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico",
{ "glob": "package.json", "input": "../", "output": "./assets/" }
],
}
The solution allows the file to be available from the outside therefore making GET requests possible.

Related

Nuxt typescript building and transpile project for deployment

I have a Vue application built with the NuxtJS framework using the yarn create nuxt-app utility.
The application is meant to be for Server-Side-Rendering meaning it has to run on an actual server instance.
I am using Nuxt-ts to be able to use typescript with Nuxt, my nuxt.config.js looks like this:
export default {
ssr: true,
srcDir: 'src/',
buildModules: [
// https://go.nuxtjs.dev/typescript
'#nuxt/typescript-build',
// https://go.nuxtjs.dev/stylelint
'#nuxtjs/stylelint-module',
],
server: {
port: envsConfig.env.ENV_CP_HTTP_PORT || 2055,
}
}
When building using nuxt-ts build, I get a folder .nuxt with the results of the build phase,
My scripts are:
"scripts": {
"dev": "nuxt-ts",
"build": "nuxt-ts build",
"start": "nuxt-ts start"
}
The question now, how can I deploy this on a server and run it using node?
Cuz running node .nuxt/dist/server/server.js doesn't seem to work, and I got confused.
Also, nuxt-ts seems to transpile in runtime, where I want my application to be built+transpiled then copy the results and run them using node,
Any help would be awesome!
Thanks
First, nuxt-ts isn't mandatory. It's only useful for .ts files not compiled by webpack (typically the nuxt.config.ts). If you have nuxt.config.js in vanilla javascript, you can stay with the standard nuxt binary (no the nuxt-ts).
But you can keep it if you want. I'm just saying it's not mandatory for nuxt in Typescript.
That say, run nuxt build, and it will bundle everything you need for production inside .nuxt folder.
All you have to do then is publish this folder, and run nuxt start to run the production server :)

Using node pkg to create executable with npm config

I'm using pkg to create an executable for my node js application. This works great. However, I'm also using the config module to load yaml config files based on the environment. When packaging the app using pkg, I'm specifying that the config folder should be included.
"pkg": {
"assets": [
"config/*"
]
}
When I run pkg . --debug, I can see that the config files are being packaged up. However, if I then rename the config folder, delete the folder, or just move the newly packaged exe to a different folder, it says No configurations found in configuration directory:C:\Users\me\folderwithexe\config (this config directory doesn't exist because I moved the exe to a new folder)
From what I can tell, the config module appears to be looking for the config folder relative to where the exe is being executed. It's not getting it from the packaged exe file even though it's in there. So if you were to run this exe on another computer (which is the plan), then it's looking for the config folder outside of the exe. None of the other modules appear to have this problem. It's just this config module.
Any idea how I can get the pkg module and the config module to work together?
Here is my full package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "",
"main": "app.js",
"author": "Me",
"license": "UNLICENSED",
"dependencies": {
"config": "^3.3.1",
"js-yaml": "^3.14.0",
},
"bin": "app.js",
"pkg": {
"assets": [
"config/*"
]
}
}
The pkg will bundle every require dependency and every assets or scripts that it found in configuration lists (assets and scripts). So, first you need to keep your config files away from pkg.
To keep pkg away from your config files, you can use a variable path that pkg can't resolve, by example:
const config = require(path.join(__dirname, 'config/config.json'));
At this point the pkg don't bundle your config file, but if you run the build, you notice that the path of your config.json is something like /snapshot/config/config.json (https://www.npmjs.com/package/pkg#snapshot-filesystem)
The alternative is to get the config file from binary path using the process.execPath:
const config = require(path.join(process.execPath, "../","./config/config.json"));
After that, the executable will get the config file from "relative path" of running directory.
I don't test with the config module but I thing if you remove the assets: ["config/*"] from the pkg property from package.json and add the new path to the config module (above) it will work.
process.env["NODE_CONFIG_DIR"] = path.join(process.execPath, "../","./config/");
const config = require("config");

How to install and configure Syncfusion JavaScript with Aurelia CLI?

How do I configure Syncfusion JavaScript for use with Aurelia via Aurelia CLI?
Here is how Syncfusion JavaScript configured when used with jspm (via http://aurelia-ui-toolkits.github.io/demo-syncfusion/#/installation):
Open config.js and add a couple of path mappings:
paths: {
"*": "src/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*",
"common/ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/common/ej.*.js", <----
"datavisualization/ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/datavisualization/ej.*.js", <----
"ej.*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/scripts/ej/web/ej.*.js", <----
"syncfusion-javascript/*": "jspm_packages/github/syncfusion/JavaScript-Widgets#14.1.0.41/*" <----
},
"map": {
"aurelia-bootstrapper": "npm:aurelia-bootstrapper#1.0.0-beta.1",
"aurelia-fetch-client": "npm:aurelia-fetch-client#1.0.0-beta.1",
"aurelia-framework": "npm:aurelia-framework#1.0.0-beta.1.0.2",
"jquery": "npm:jquery#2.2.3", <----
"jquery.min": "npm:jquery#2.2.3", <----
"jquery-easing": "npm:jquery.easing#1.3.2", <----
"jquery-validation": "npm:jquery-validation#1.15.0", <----
"jquery-validation-unobtrusive": "npm:jquery-validation-unobtrusive#3.2.6", <----
"jsrender": "npm:jsrender#0.9.75", <----
}
Check out the Aurelia CLI documentation on how to add libraries to your project.
Your basic steps will probably be to install the package via npm:
npm install syncfusion-javascript --save
That will add the package to your project.json file and have it downloaded.
Next you're going to want to configure your aurelia.json file. Because SyncFusion is not modular, and is really just a library of files, there is no way to just reference a package and have it bundled. What you'll have to do is create a package for each of the packages you're using.
Or, alternate solution, create your own javascript "main" file that references all the modules in the package you want, and set that as the "main" in the package description
{
"name": "syncfusion-javascript",
"path": "../node_modules/syncfusion-javascript",
"main": "syncFusionCustomMain"
}
Your syncFusionCustomMain.js file would import the files from the node_modules folder, and then export the functions to be referenced appropriately.
Sorry this is kind of bad news for you. This package is just not loader friendly, and as of right now, the CLI doesn't have support for just defining paths (since everything gets bundled, it needs to have everything be explicit at compile time).

Browserify overrides its own configuration when browsing a folder that contains a package.json?

I've created a simple JavaScript application using AngularJS.
I'm using npm and Bower to manage my dependencies, Gulp to automatise my tasks and I want to use the CommonJS' module.exports/require() to tie everything up together: I decided to go for Browserify to bundle this all up.
There's my very empty and clean project on Github, if you wanna take a look.
In order to be able to require('angular'), I configured Browserify to shim that AngularJS into the available modules, using browserify-shim. Pretty straightforward, here's the relevant part of my package.json:
"browser": {
"angular": "./bower_components/angular/angular.min.js"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"angular": {
"exports": "angular"
}
}
It's pretty neat, my main JS file now looks like this:
'use strict';
var angular = require('angular');
angular.module('MyApp', [])
.controller('View1Ctrl', ['$scope', require('./view1/view1.js')])
.controller('View2Ctrl', ['$scope', require('./view2/view2.js')]);
And that works.
Now, I'm trying to get into some more advanced stuff, using external libraries available through Bower. They get installed under bower_components and look -well- just like my project, they've got a package.json, a bower.json and all.
Take for example ng-dialog, which also require('angular'). Once retrieved via bower install ng-dialog --save, I do two things:
Link their dist's JS file to a keyword (let's say ng-dialog) in my package.json
require('ng-dialog') in main main JS file in order to have my Angular module depend on theirs.
Here's the updated relevant part of my package.json (note that ng-dialog does not need to be shimmed):
"browser": {
"angular": "./bower_components/angular/angular.min.js",
"ng-dialog": "./bower_components/ng-dialog/js/ngDialog.min.js"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"angular": {
"exports": "angular"
}
}
... and my updated app.js file:
'use strict';
var angular = require('angular');
require('ng-dialog');
angular.module('MyApp', ['ngDialog'])
.controller('View1Ctrl', ['$scope', require('./view1/view1.js')])
.controller('View2Ctrl', ['$scope', require('./view2/view2.js')]);
I get the following error while Browserify-ing this up:
Error: Cannot find module 'angular' from 'C:\...\bower_components\ng-dialog\js'
After a good half hour of tweaking around, it turned out that SIMPLY deleting the package.json file from bower_components/ng-dialog makes it all go smoothly.
What is going on and how the hell should I bundle that ngDialog.min.js?
As stated in the Browserify Handbook
The module system that browserify uses is the same as node, so packages published to npm that were originally intended for use in node but not browsers will work just fine in the browser too.
Increasingly, people are publishing modules to npm which are intentionally designed to work in both node and in the browser using browserify and many packages on npm are intended for use in just the browser. npm is for all javascript, front or backend alike.
Therefore use the npm distribution of Angular and ngDialog packages rather than the bower ones
npm install angular ng-dialog --save
This will do away with the need to do the whole configuration in package.json and simply calling require() in the project will make browserify work.
When we require any node module in the project, browserify bundles the file present in the main field of the package.json of that respective node module. Currently as ngDialog's main field references the ngDialog.js file , therefore you will need to change it to ngDialog.min.js so that browserify bundles that file. (This isn't a major issue as you compress your browserify bundle using gulp-uglify)
I have forked your code and done the necessary changes in it - Check them here https://github.com/pra85/angular-seed

How to require a file other than the npm main file in node?

package.json:
...
"name": "mypackage",
"main": "src/index.js"
...
Directory structure:
|- src/
|--- index.js
|--- other.js
I can require src/index.js with require('mypackage');, but how can I require src/other.js?
If the answer is require('mypackage/src/other');, is there a way to make it so I can require it with require('mypackage/other'); (i.e. teaching node what the source file directory is of your module?
AFAIK You'll have to explicitly expose it in the root:
Directory structure:
|- src/
|--- index.js
|--- other.js
|- other.js
Then in /other.js
module.exports = require('src/other.js');
Now you can do require('mypackage/other')
I'm currently looking into the exact same thing.
Package.json has a property called 'files':
http://blog.kewah.com/2014/npm-as-a-front-end-package-manager/
https://docs.npmjs.com/files/package.json
The "files" field is an array of files to include in your project. If you name a folder in the array, then it will also include the files inside that folder.
But I have yet to find how to do a import/require of such a file.
I don't really see another point in listing these files other then to be able to import/require them?
I was able to import a file from a package if it was listed in this files array.
{
"name": "local-ui-utilities",
"version": "0.0.1",
"description": "LOCAL UI Utilities",
"main": "index.jsx",
"author": "Norbert de Langen",
"license": "none",
"dependencies": {
},
"files": [
"/colors/sets/variables.css"
]
}
I'm able to import the css file from the package using postcss-import:
#import "local-ui-utilities/colors/sets/a.css";
This probably isn't your use-case, but postcss-import just uses npm under the hood. So This should work for your use-case as well, I would think.
This question and accepted answer seem related:
Node/NPM: Can one npm package expose more than one file?
You'll have to explicitly expose the file in the root folder, but many projects (including older versions of lodash) do this as part of a pre-publish step. In fact there's a package that does exactly what #Creynders suggests, adding module.exports = require('./path/to/file') files in your root folder. A while back I wrote up a guide on getting started, but the gist is pretty simple.
Install
npm install --save-dev generate-export-aliases
Configure
{
"name": "my-package",
"scripts": {
"prepublish": "generate-export-aliases"
},
"config": {
"exportAliases": {
"other": "./src/other"
}
}
}
Use
const other = require('my-package/other')
DISCLAIMER: I'm the author of the package
Edit
Don't use prepublish anymore. Instead, use prepublishOnly.
My own approach to the solution:
As no one has an idea of how to perform the desired behaviour, we can't stand still, the best answer now is:
Solution 1:
From Patrick solution, and his package generate-export-aliases: we can add some npm scripts to automate the whole publish process.
Either you write your code directly in commonjs inside ./src/ subdirectory or you used some new shining ES feature transpiled in ./dist, you will have your module files to be exposed, so add npm scripts:
"scripts": {
"expose": "generate-export-aliases",
"prepublishOnly": "npm run expose",
"postpublish": "git reset --hard HEAD"
}
Or a more save scripts
"scripts": {
"expose": "generate-export-aliases",
"prepublishOnly": "git ceckout -b prepublish-expose && npm run expose",
"postpublish": "git add . && git stash && git stash drop && git checkout master && git branch -d prepublish-expose"
}
Solution 2: Without generate-export-aliases
You can use gulp task runner (transpile if needed and put the files directly in the root dir, no need to copy or move again).
Indeed, this is the exposing step, you can keep prepublishOnly and postpublish scripts unchanged and just change the expose script. Save time and build in the root dir directly.
From node 12.7.0 there is the [exports][1] property of the package.json that can help you.
{
"main": "./main.js",
"exports": {
".": "./main.js",
"./other": "./src/submodule.js"
}
}```
If you have a lot of submodules and you want to export all files you can use a [subpath pattern][1]:
```//package.json
{
"exports": {
"./*": "./src/*.js"
},
}```
[1]: https://nodejs.org/api/packages.html#subpath-patterns
just import it as a simple file.
const otherfile = require('./node_modules/other_package/other_file.js');

Categories