Importing bower component library into Angular 2 application - javascript

I am working on an Angular 2 application in ASP.NET Core and I am trying to import oidc-client (https://github.com/IdentityModel/oidc-client-js) into one of my Typescript files. The oidc-client files were installed via bower which placed them in the expected bower_components folder. The oidc-client.js file is copied to the lib folder under wwwroot via a gulp task on build.
My directory structure looks like this (only relevent portions represented):
wwwroot
|
--app
| |
| --shared
| |
| --auth
| |
| --token.service.ts
--lib
| |
| --oidc-client
| |
| --oidc-client.js
|
--bower_components
| |
| --oidc-client
| |
| --dist
| | |
| | --oidc-client.js
| --oidc-client.d.ts
|
--typings
|
--index.d.ts
I need to use the oidc-client library in my token.service.ts file so I am doing this:
import { Oidc } from './lib/oidc-client/oidc-client';
But this results in an error 'Cannot find module './lib/oidc-client/oidc-client'.
I've tried different variations on the path, relative and non-relative, and I can't seem to figure out how to import the oid-client library.
Maybe its the typings not working? Do I need to do anything special with the d.ts file to make it work?
Thanks for any guidance.

As mentioned in a comment made above, using the NPM distribution of oidc-client would be the preferred option.
However, the typings that are included in the oidc-client are a little strange. Usually, the typings .d.ts file sits side-by-side with the .js file. With oidc-client, they are in different directories and that's what's causing problems with your import statement.
If you install the NPM module and add node_modules/oidc-client/oidc-client.d.ts to the files configuration of your tsconfig.json:
{
"files": [
"index.ts",
"node_modules/oidc-client/oidc-client.d.ts"
]
}
You should be able to create an index.ts file that imports oidc-client:
import { OidcClient } from "oidc-client";
If the .d.ts file and the .js file had been side-by-side, your import would have worked, but they are not, so it doesn't.
If you do not want to use the NPM distribution, it is likely that the separation of the .d.ts and .js files is what's causing the problem with the Bower distribution, too.

Related

How to initialize a mono repo and create-react-app inside monorepo?

I want to initialize a monorepo, and then initialize apps inside the packages folder. I found a bunch of examples of how to do this. But, what I want to achieve is, I want to keep all the node_modules at the root level.
--monorepo
|--node_modules
|--packages
| |--create-react-app-1
| | |--src
| | |--{...rest}
| |--create-react-app-2
| | |--src
| | |--{...rest}
|--package.json
So, all the node_modules are at the root level and all the packages are using them from the root level. All the dependencies and dev-dependencies are listed in the root level package.json.
I want to use yarn as the package manager as well.
How I can achieve this?

angular2 spring-boot project structure

I have a new angular2 project that was built using the standard file structure described in the quickstart. I am attempting to build an API gateway and have spring-boot host my application, however I haven't been able to configure boot to use the /dist directory in my project where the generated sources are created. The project structure is as follows:
project
|--dist
|--node_modules
|--src
| |--app
| |--assets
| |--main
| | |--java
| | |--resources
| | | |--config
| | |--webapp
| | | |--WEB-INF
I would like to use the default /dist directory so that I can still use npm/webpack for continuous development on the UI.
I tried configuring the static resources directory like so:
spring.resources.staticLocations: /dist
But this doesn't seem to be working.
I created a resource handler to point directly to the dist directory:
#Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
String currentPath = new File("./").getAbsolutePath();
currentPath = "file:///" + currentPath;
registry.addResourceHandler("/**").addResourceLocations(currentPath + "/dist/");
}
}
This solves part of the problem but now my root URL ('/') no longer maps to index.html.
Is there an easier/better way to configure spring-boot to find the /dist project directory? Should my project structure change? I would really like to get all of these pieces working together cleanly.
Spring Boot will automatically add static web resources
located within any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
The folders are relative to src/main/resources
If you put index.html like below, then spring can serve your file
without any configuration.
src/main/resources/META-INF/resources/index.html
src/main/resources/resources/index.html
src/main/resources/static/index.html
src/main/resources/public/index.html
I took #chrylis advice and pointed the destination directory for the webpack build to build/dist (using Gradle).
I avoided putting the generated sources in /resources/** because eventually this will get built into a .war and deployed to an enterprise application server -- I didn't want a lot of include/exclude logic in my build to support this. Plus the build directory seemed a more logical place for the generated .js source.
My project structure now looks like this:
project
|--build
| |--dist
| |--...
|--node_modules
|--src
| |--app
| |--assets
| |--main
| | |--java
| | |--resources
| | | |--config
| | |--webapp
| | | |--WEB-INF
I eliminated the WebMvcConfigurerAdapter and configured the static resources to point to my dist directory in build:
spring.resources.static-locations: "file:./build/dist/"
I'm now able to run Webpack, Spring-Boot or deploy to my application server with the same source and very little configuration overhead.

How do you keep the order of AngularJS files when transpiling with BabelJS

I've started to play around with using NPM Scripts and BabelJS to transpile my ES2015 AngularJS project. The problem is that the concatenated order is not correct and causes nomod errors.
Given this directory structure:
MyApp
+- src
| +- dashboard
| | +- search-bar
| | | +- search-bar.directive.js
| | | +- search-bar.service.js
| | | +- search-bar.spec.js
| | +- dashboard.module.js
+- dist
| +- js
| | +- dashboard.js
Ideally, dashboard.module.js should be the first file because that is where the actual dashboard module is created, followed by everything in /search-bar which actually doesn't require any order at all. The search bar is a feature/component, not a new module and is all part of dashboard.
The problem seems to be that simply running BabelJS will just concatenate all the files together using the same structure as the filesystem does.
babel ./src/dashboard/**/*.js -o ./dist/js/dashboard.js
There are also weird things when messing with the wildcards to try make sure all files are captured.
How can I process dashboard.js first before any of the other components?
It turns out you can specify many globs as input files.
Try using this command:
babel ./src/dashboard/*.js ./src/dashboard/**/ -o ./dist/js/dashboard.js
This will first process any .js immediately inside of /dashboard followed by the rest of the directory.
Gotcha: This will only really work as long as you only have the one file inside of the /dashboard root. If you were to add dashboard.config.js or any other file, then this would process those files in that filesystem order. Unfortunately, dashboard.config.js comes before dashboard.js so your problem will continue. :(
Also, if you have other files in /dashboard root or you have other kinds of .js that you don't want to be included, you'll need to ignore them.
Try:
babel ./src/dashboard/**/*.js ./src/dashboard/**/ --ignore *.spec.js --ignore *.conf.js -o ./dist/js/dashboard.js
This will put things in the right order and also skip any karma.config.js or search-bar.service.spec.js files you may put in there. I assume that you don't want those actually being used in production.

Using dotenv in a Node JS module

I am building a Node app that returns results for a search using a Google Custom Search Engine(CSE).
I am going to separate the part of the app that sends the request to Google and returns the results into a module.
I use dotenv already in the app to store MongoDB credentials and the app's URL.
I also want to use dotenv in the module to store the Google CSE ID and the API key for the CSE.
I want my module to work independently of the main app but also to use the main app's dotenv file when it's a module.
Currently my module structure looks like this:
module
|
+-- node_modules
| |
| \-- dotenv
| |
| \-- (dotenv module's files....)
|
+-- .env
|
\-- index.js
This works perfectly on its own. The .env file stores the required environment variables and I can access them in the index.js file by requiring the dotenv module.
When included in the main app the structure looks like this:
app
|
+-- node_modules
| |
| +-- dotenv
| | |
| | \-- (dotenv module's files....)
| |
| \-- my_google_search_module
| |
| +-- node_modules
| | |
| | +-- dotenv
| | |
| | \-- (dotenv module's files...)
| |
| \-- index.js
|
+-- .env
|
\-- index.js
This also works. I store all the environment variables in the main app's .env file and by requiring dotenv in the app's index.js I can access those variables. Plus, the "my_google_search_module" seems to be pulling its required variables from the .env file in the root of the app. There is no .env file in the module.
My question is am I doing this the right way?
I have researched this further and can confirm that the module's .env is pulling the required environment variables from the app's .env file.
I believe this section from the dotenv readme, though not exactly related, verifies that -
https://www.npmjs.com/package/dotenv#what-happens-to-environment-variables-that-were-already-set
We will never modify any environment variables that have already been
set. In particular, if there is a variable in your .env file which
collides with one that already exists in your environment, then that
variable will be skipped. This behavior allows you to override all
.env configurations with a machine-specific environment, although it
is not recommended.
Yes, you are doing in a right way. There must be a single .env file in a whole project. But there is a trick to include it in the different directory structure.
For example:
Your index.js file is in /app/src, your .env file is in /app. Your index.js file has this
dotenv.config({path: "../.env"});
You could also use dotenv.config({path: path.join(__dirname, "../.env")});
for node projects, i would suggest to use npm package dotenv. You can find details on how to use it. do not forget to include require('dotenv').config() at the start of your project file, say index.js.
Now you can use .env contents anywhere you need. For example i want my server port to be 4000 which i define in .env as PORT=4000. Now, to use .env variables anywhere, simply provide variable name in suffix such as process.env.PORT. That is it. Though i am late on this post, hope this could be of any help.

avoiding deep nested module imports in an ES6 JavaScript web project

I am trying to tackle that I am currently have with my JavaScript project structure. I am writing ES6 syntax with webpack. My current directory structure looks like this
project-dir
|_ packages.json
|_ webpack.config.js
|_ html
| |_ ***
| |_ ***
|_ js
|_ app.js
|_ routes
|_ abc-component
| |_ components
| | |_ abc1.js
| | |_ abc2.js
| |_ index.js
|
|_ xyz-component
| |_ components
| | |_ xyz1.js
| | |_ xyz2.js
| |_ index.js
|_ reducers.js
This is simpler structure. But the problem is that the "reducers.js" and the "abc1.js/xyz1.js" need access to the same functionality. So, if that functionality lives in "reducers.js" then the "abc1.js/xyz1.js" would have to import it as "../../reducers.js". If that functionality lives split up in "abc1.js" and "xyz1.js" etc, then "reducers.js" will have to import each one of them as ".\abc-component\components\abc1.js" and ".\xyz-component\component\xyz1.js". The first way, it feels like i am reaching way up and the second way, it feels like i am reaching way up. The code is also constrained to the structure of the file layout. This directory structure could go deeper down and we will end up with very ugly imports.
So, it makes sense for me to pull out this functionality that is shared by reducers.js and "abc1/js/xyz1.js" into a different module. In doing that i thought about putting that in a another git repo, but this functionality is very project specific and didn't want the hassle of putting it in another repo.
I tried creating a "lib" folder under the "js" folder and put the common functionality it in that folder along with a packages.json file. That way, i thought i would just add it as a "dependencies" in the project's package.json file with the "file:\lib\common" value. This way, it will reference that module locally. But this landed me in a load of trouble. The problems i am encountering are 1) I couldn't write ES6 in this common module since webpack is not processing it 2) Everytime I change something in the common.js, i have to run "npm install" 3) npm seems to be caching an old version of the common module ever after i change it and run "npm install". Not sure where it comes from, i did clean the npm cache by running "npm cache clean" 4) Even when i just write old javascript in this common module and not ES6, webpack watch does not pick up on changes to this file and re-render the app.
I was wondering if i could get some thoughts on how best to go about solving this problem. Also, thoughts about how i tried and exceptionally failed in solving the problem with a local module would be very helpful.
One way to deal with this is to put your common code into a node module and just import it like you would any other library.
This would work similarly to the "lib" idea you suggested but without needing relative imports.

Categories

Resources