How to access a project's package.json file from an installed package - npm

I've written a React component that I've published on npm (reactify-markdown). The component's props allow the user to specify which markdown-it plugins they'd like included when rendering. I assume in the common case (i.e. in my case), this set of plugins will be the same for the entire project.
I'd like to create an optional custom config section in the importing project's package.json that includes a list of plugins and rules used when configuration markdown-it's role in reactify-markdown, akin to markdown-it-loader's options.use syntax.
my-project/package.json
{
"dependencies": {
// ...
"markdown-it": "*",
"markdown-it-underline": "*",
"reactify-markdown": "*",
// ...
}
// ...
"reactify-markdown": {
"use": [
"markdown-it-underline",
"./src/markdown-it/my-custom-renderer.js"
],
"disable": [ "link" ],
"enable": [ "image" ]
}
}
How would I go about accessing this section from inside my reactify-markdown code?
The ugly solution is to walk the directory structure up until it finds a package.json file, but I foresee all kinds of issues with that (permissions issues, following symbolic links, etc).

Related

Polymer service worker caching and routing issues

I have a very standard Polymer 2 application with the following polymer.json file:
{
"entrypoint": "index.html",
"shell": "src/my-app.html",
"autoBasePath": true,
"fragments": [
"src/my-page-stats.html",
...
"src/my-page-404.html"
],
"sources": [
"images/**/*",
"src/**/*",
"libs/**/*"
],
"extraDependencies": [
"bower_components/webcomponentsjs/*.js",
"!bower_components/webcomponentsjs/gulpfile.js",
"manifest.json",
"src/lib/Utils.js"
],
"lint": {
"rules": ["polymer-2"]
},
"builds": [
{
"preset": "es5-bundled"
},
{
"preset": "es6-bundled"
},
{
"preset": "es6-unbundled"
}
],
"lint": {
"rules": ["polymer-2"],
"ignoreWarnings": ["invalid-polymer-expression"]
}
}
The libs directory contains a bunch of symlinks:
total 12
Sortable.js -> ../bower_components/Sortable/Sortable.js
datalist-polyfill.min.js -> ../../node_modules/datalist-polyfill/datalist-polyfill.min.js
ejs.js -> ../../node_modules/ejs/ejs.js
ejs.min.js -> ../../node_modules/ejs/ejs.min.js
leaflet -> ../../node_modules/leaflet/dist/
moment-precise-range.js -> ../../node_modules/moment-precise-range-plugin/moment-precise-range.js
moment-timezone-with-data.js -> ../../node_modules/moment-timezone/builds/moment-timezone-with-data-2012-2022.js
moment.js -> ../../node_modules/moment/moment.js
I am having several problems with the service worker, and I can't figure out what to do:
The libs folder is not getting cached. If the network is down, the browser will attempt to load all of the files in libs. I thought it would since under sources in my polymer.json I have "libs/**/*" I wonder if them being links is a problem?
The route routes/appInfo.js must get cached, and it doesn't right now. It's a dynamic Javascript file that sets a global variable, used throughout the application. It doesn't get cached because it's not mentioned anywhere as a "special" file, but... it is.
The route /routes/passwordRecover/** must be ignored by the service worker. The problem right now is that if a user requests a password recovery token, and they have already loaded the site before, the request gets handled by the service worker which redirects them straight to the default index.html. So, the reset never actually happens.
The problem here is that I am not even sure what files to change. I looked at the official documentation for service worker in Polymer 2.0 but I still have questions.
For example:
If I specify --sw-precache-config config-file.json, I have to write a config file on my own from scratch. Is there a way to see the default "starting point" at least, so that I don't make silly mistakes?
How do I force specific URLs to be cached (see routes/appInfo.js), how do I prevent others from being cached (see /routes/passwordRecover/**) and how do I check why libs/** are not being cached?

Configuring service worker in Polymer 2.X

I need to configure the service worker for the first tine, and I am totally lost.
I have a very standard Polymer 2 application with the following polymer.json file:
{
"entrypoint": "index.html",
"shell": "src/my-app.html",
"autoBasePath": true,
"fragments": [
"src/my-page-stats.html",
...
"src/my-page-404.html"
],
"sources": [
"images/**/*",
"src/**/*",
"libs/**/*"
],
"extraDependencies": [
"bower_components/webcomponentsjs/*.js",
"!bower_components/webcomponentsjs/gulpfile.js",
"manifest.json",
"src/lib/Utils.js"
],
"lint": {
"rules": [
"polymer-2"
]
},
"builds": [
{
"preset": "es5-bundled"
},
{
"preset": "es6-bundled"
},
{
"preset": "es6-unbundled"
}
],
"lint": {
"rules": [
"polymer-2"
],
"ignoreWarnings": [
"invalid-polymer-expression"
]
}
}
The libs directory contains a bunch of sym links:
total 12
Sortable.js -> ../bower_components/Sortable/Sortable.js
datalist-polyfill.min.js -> ../../node_modules/datalist-polyfill/datalist-polyfill.min.js
ejs.js -> ../../node_modules/ejs/ejs.js
ejs.min.js -> ../../node_modules/ejs/ejs.min.js
leaflet -> ../../node_modules/leaflet/dist/
moment-precise-range.js -> ../../node_modules/moment-precise-range-plugin/moment-precise-range.js
moment-timezone-with-data.js -> ../../node_modules/moment-timezone/builds/moment-timezone-with-data-2012-2022.js
moment.js -> ../../node_modules/moment/moment.js
Now, I am having several problems with the service worker, and I can't figure out what to do:
The libs folder is not getting cached. If the network is down, the browser will attempt to load all of the files in libs. I thought it would since under sources in my polymer.json I have "libs/**/*" I wonder if them being links is a problem?
The route routes/appInfo.js must get cached, and it doesn't right now. It's a dynamic Javascript file that sets a global variable, used throughout the application. It doesn't get cached because it;s not mentioned anywhere as a "special" file, but... it is.
The route /routes/passwordRecover/** must be ignored by the service worker. The problem right now is that if a user requests a password recovery token, and they have already loaded the site before, the request gets handled by the service worker which redirects them straight to the default index.html. So, the reset never actually happens.
The problem here is that I am not even sure what files to change. I looked at the officual documentation for service worker in Polymer 2.0 but I still have questions.
For example:
If I specify --sw-precache-config config-file.json, I have to write a config file on my own from scratch. Is there a way to see the default "starting point" at least, so that I don't make silly mistakes?
How do I force specific URLs to be cached (see routes/appInfo.js), how do I prevent others from being cached (see /routes/passwordRecover/**) and how do I check why libs/** are not being cached?

Exclude components code from production environment in Angular

I would like to exclude certain components from my production build in Angular 5+. So far I have read around and I understand the concepts of environment variables, but to my understanding those are available at runtime. What I am looking for is to actually exclude certain modules from ever being imported so that the code for them does not get to the production build (files).
I also dont want to have an
<div *ngIf="isProduction">...</div> laying around, what I would rather want to do is something like this:
Component({
...
templateUrl: environment.production ? 'app.prod.html' : 'app.html'
})
However this is also not possible due to how the Angular compiler works.
I guess the answer to this is to tweak the angular-cli, but given there is no good documentation (that I can find), I'd like to know if someone perhaps has a better idea?
For those looking for a *not so scalable* solution.
Solution is for Angular 5 / Angular 6+
You can switch specific files depending on what environment you are building/serving by adding each file pair in the angular.json file.
For example, if you wish to use app.prod.html instead of app.html in your app component only when using the production environment / configuration.
In angular.json add your replacments in the fileReplacements array under the config you wish to have replaced:
{
...
"projects": {
...
"configurations": {
"production": {
...
"fileReplacements": [
...
*** ADD YOUR REPLACEMENT FILES HERE ***
...
]
}
}
}
}
Using the above example:
{
...
"projects": {
...
"configurations": {
"production": {
...
"fileReplacements": [
...
{
"replace": "src/app/app.html",
"with": "src/app/app.prod.html"
}
...
]
}
}
}
}
Not a pretty solution as it seems you will be doing this for each file you wish to replace but it should work nontheless.
Build or serve the specific config with
ng serve --configuration=production
ng build --configuration=production

What is the proper folder structure for a polymer app?

I've got an app with several custom elements in it, and I'm writing tests, and I'm not sure how the directories are supposed to be set up for tests to work.
Is it something like:
myApp
myApp/bower_components
myApp/test
myApp/test/myApp
myApp/test/myElement1
myApp/test/myElement2
myApp/test/myElement3
myApp/src
myApp/src/myApp
myApp/src/myElement1
myApp/src/myElement2
myApp/src/myElement3
myApp/demo
Or does each element get a test/ subfolder? Like
myApp/src/myElement1/test
myApp/src/myElement2/test
myApp/src/myElement3/test
According to the docs here each element has a test folder that can be accessed via the browser when you use polymer serve like so localhost:8080/components/my-el/test/my-el_test.html
The test should be in their own folder separated from the app main directory to facilitate the Polymer CLI's build process. (Making your app production ready.)
Recommended Structure:
myApp/test/myElement1
myApp/src/myElement1
Here’s an example polymer.json file from the Shop app: ((No Test Folder))
polymer.json
{
"entrypoint": "index.html",
"shell": "src/shop-app.html",
"fragments": [
"src/shop-list.html",
"src/shop-detail.html",
"src/shop-cart.html",
"src/shop-checkout.html",
"src/lazy-resources.html"
],
"sources": [
"src/**/*",
"data/**/*",
"images/**/*",
"bower.json"
],
"extraDependencies": [
"manifest.json",
"bower_components/webcomponentsjs/webcomponents-lite.js"
],
"lint": {
"rules": ["polymer-2-hybrid"]
}
}

Reusing/sharing views & models in different projects with Durandal JS

I'm building multiple applications using Durandal JS. All those applications are located on the same server under the same document root and share some common code. For example they all use the same model & view for login.
How can i reuse/share the login model & view in all those applications without just copy & pasting the files to the projects?
I already tried something with the following folder structure:
ProjectsDir/Project1/app/durandal/..
/models/Shell.js, Main.js, ...
/views/Shell.html, Main.html, ...
/main.js
/main-built.js
ProjectsDir/Project2/app/durandal/..
/models/Shell.js, Main.js, ...
/views/Shell.html, Main.html, ...
/main.js
/main-built.js
ProjectsDir/ProjectsBase/app/models/Login.js
/views/Login.html
This way it would be possible to reference the same login model & view in my ProjectsBase from all other projects by setting the correct route to it in the respective shell.js. This route could look something like this:
router.map([
{
url: 'Login',
moduleId: '../../ProjectsBase/app/models/Login',
name:'Login',
visible: true
},
{
url: 'Main',
moduleId: 'models/Main',
name:'Main',
visible: true
}
]);
This works as expected during debugging but building the production version with the durandal optimizer unfortunately doesn't work.
Actually building does work (it produces the main-built.js just fine) but when i launch the site with the production file referenced i get the following error:
Uncaught Error: undefined missing durandal/../../../MPBase/durandal-app/models/Login
I'd really appreciate any ideas on how I could make the built production file work with the setup I described above.
Of course I'm also open for other ideas on how to make models & views reusable/sharable between multiple projects.
Thanks
With some help from Durandals Google Group I found a solution.
It's not possible to use the provided optimizer.exe but it's quite easy to create a custom r.js config which can handle the setup I described in the question:
First of all I ran the optimizer.exe which created a basic config file (app.build.js) that i used as a starting point.
This config file automatically included all necessary files from the project itself (e.g. Project1).
The only things that are missing in this config file are the references to my shared code (the login files from the ProjectsBase directory). Therefore I added them manually along with a new path.
Custom app.build.js (3 changes highlighted with a comment, the rest is how it was built from the optizimer.exe):
{
"name": "durandal/amd/almond-custom",
"inlineText": true,
"stubModules": [
"durandal/amd/text"
],
"paths": {
"text": "durandal/amd/text",
"projectsbase": "../../ProjectsBase/" // New path to folder with shared files
},
"baseUrl": "ProjectsDir\\Project1\\app",
"mainConfigFile": "ProjectsDir\\Project1\\app\\main.js",
"include": [
"main",
"durandal/app",
"durandal/composition",
"durandal/events",
"durandal/http",
"text!durandal/messageBox.html",
"durandal/messageBox",
"durandal/modalDialog",
"durandal/system",
"durandal/viewEngine",
"durandal/viewLocator",
"durandal/viewModel",
"durandal/viewModelBinder",
"durandal/widget",
"durandal/plugins/router",
"durandal/transitions/entrance",
"projectsbase/app/models/Login", // Include for login model
"models/Main",
"models/Shell",
"text!projectsbase/app/views/Login.html", // Include for login view
"text!views/Main.html",
"text!views/Shell.html"
],
"exclude": [],
"keepBuildDir": true,
"optimize": "uglify2",
"out": "ProjectsDir\\Project1\\app\\main-built.js",
"pragmas": {
"build": true
},
"wrap": true,
"insertRequire": [
"main"
]
}
Now I only had to update my Shell.js to use the correct routes to the Login model & view by also adding a path to requirejs and using it correctly when setting the routes:
Add path at the very beginning of Shell.js:
requirejs.config({
paths: {
'projectsbase': '../../ProjectsBase/'
}
});
Set correct routes in activate method of Shell.js:
router.map([
{ url: 'Login', moduleId: 'projectsbase/app/models/Login', name:'Login', visible: true },
{ url: 'Main', moduleId: 'models/Main', name:'Main', visible: true }
]);
Now i can build my main-built.js which bundles & minifies all relevant files by opening the node js command line, browsing to the directory where the r.js config file is and create the build (the main-built.js) with the following command:
node r.js -o app.build.js
This way everything is included correctly when I'm working with the debug files and it's also working with the build main-built.js which also includes my shared files from the ProjectsBase.

Resources