How to conditionally import different files during build in Angular 6? - javascript

Overview
I have Angular 6 app build by Angular CLI. Application is written in multiple languages. Each language has JSON file with translations of all the application texts. The filenames are ${language}.json, e.g. en.json, es.json, pl.json.
I'd like to set the language of the app during build - build the app only in one language. For that on build I need to import a single translation file, which is chosen depending on which language I'm building for.
Problem
How to conditionally import single translation file only for the language chosen during build?
In addition I'd like the translation file to be bundled together with the rest of my application's JavaScript, instead of being loaded on demand on run-time.
Sketch of a solution
const translations = import(`./translations/${lang}.json`);
Actually the above code works in Angular 6/Webpack (the only thing needed is setting compilerOptions.module: 'ESNext' in tsconfig.app.json), but not in a way that I want. Instead of resolving the import during build time and bundling the translation file together with the rest of the code, it creates a separate files (chunks) for all translations, one of which is then loaded on demand during run-time depending on the value of JavaScript lang variable.
So how do I make the import to be resolved during build-time and not run-time? Also where and how do I set lang variable during build, as I don't have access to Webpack configuration (it's hidden inside Angular CLI)
Webpack alone
When using Webpack alone, it's possible to implement this for example by using NormalModuleReplacementPlugin. But as Angular CLI hides all the Webpack configuration, I don't know how to integrate it into Angular project. Ejecting Webpack configuration from Angular CLI is the last resort for me.

As part of the CLI 6.1 release, a feature was added that allows files to be replaced during the build other than .ts files. Previously this was used for the environment and environment.prod files
Additional files can now be set with the fileReplacements key of the angular.json configurations. As far as I know, it should work with asset files, so .json should work. It's only been added recently, but there are issues/feature details that you can look up
Let us know if it works out!
P.S. If you don't want to complicate the angular.json configuration, you could create a .js node script, and run it before doing the build, passing in the language as a param, and replacing the relevant .json file in before building the Angular bundles

Related

what main.js should contained in vuejs project?

I'm learning nodejs and vuejs to modify an already created web site.
I installed nodejs, vue and vue-cli and I launched "npm run serve" which apparently start "vue-cli-serve serve"
The problem is that I don't understand what this web server do on files, in this documentation : https://cli.vuejs.org/guide/prototyping.html , it's told:
It automatically infers the entry file in the current directory - the entry can be one of main.js, index.js, App.vue or app.vue. You can also explicitly specify the entry file:
vue serve MyComponent.vue
Ok, but does it run main.js, does it include it into a js file which is the loaded by the index.html on the client broswer.
I see in the browser that the page load a js file named like that: app.23d...js
My question is how this js file is created?
For instance, when the content of main.js is this one:
import './css/icon.css'
Vue.use(VueResource)
Vue.use(VueScrollTo)
what is the output in the app....js file?
It seems it doesn't work at all like php which I usually use on web server
Thank you
Vue uses Webpack to convert your potentially-numerous distinct .js files into bundles with names like app.23d92ab88708...js
From the Webpack documentation:
Concepts
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.
I don't suggest trying to get into the details of how Webpack works
This will take a lot of time. If you have an existing Vue project, you are much better off spending your time interpreting that as a Vue project, and accepting that the conversion into the actual app.23d.....js file or files is an automatic process that you do not need to involve yourself in.
It will avoid a colossal waste of time
It won't advance your understanding of how the Vue project works
Whatever you learn about the exact workings of today's Webpack, may be completely wrong about tomorrow's Webpack.
Nevertheless the interface that Webpack provides to you as a Vue programmer will remain constant over future versions.
This is the concept of software abstraction. It is highly advantageous to not have to know how every step of every process works, as long as you know how it is designed to respond to actions you take at a high level.
Horrific thought
I have just re-read your opening sentence:
I'm learning nodejs and vuejs to modify an already created web site.
Please tell me that you are not trying to modify an already created web site where you only have the compiled website available, without the Vue source code? That would be a stupendously painful enterprise.

How to Import non npm dependency in angular

I am working on angular 5 project want to create a visualization of an application system internal connection (something like a flowchart where systems internal components like server, mq, db can be dragged upon and connection be made) component in angular. Started with the jsplumb community edition (link) to do the same. Was able to successfully integrate jsplumb into angular 5 application. The only drawback is we cannot create the new element at runtime (That is drag and drop items and create connection). This is possible in the toolkit licenced version. Which I am not considering to work with.
So was looking into js-graph-it (link) The js-graph-it is a old project works nicely with simple html page. I am having problem injecting js-graph-it.js file into the angular project. As it is non npm file it is not defined and the system does not recognize the same if syntax like import { jsgt } from '../../assets/jsgraphit/js is used. If you observer I have placed the files in my asset folder. The first question is this the right place for 3rd party js file if not present in npm? How to import or the correct way to import such files not present in npm ?
You can import 3rd party JS files into your project and be bundled by the CLI by putting them in the scripts array in your angular-cli.json config file.
This will make them part of the global scope (e.g. available on the window object) as if you imported it via a <script> tag.
You can additionally include any CSS files or other assets part of the libraries in the config file as well via the styles and assets properties.
I think the proper way for you to manage these 3rd party libs is to store them in your assets directory as it looks like you are already doing.

Loading prebuilt webpack bundles at runtime

Is it possible to require dynamic bundles at runtime with webpack? Let assume I have two separate bundles from two separate builds and I want to load modules from one bundle into another at runtime, dynamically without knowing during compilation which bundle and at what path this bundle would exist. It could be another file in directory or file from cdn.
To be detailed, prebuilt library exports something like this:
export default { Component, someFunction, otherFunction }
Every library has the same format and server provides information about path to this library at runtime. I'm thinking about something like
pathToBundle = "http://cdn" or "/bundles/name.js"
import(pathToBundle).then(module => {}).catch(error => {})
Whole gimmick is loading prebuilt bundles that are dynamically defined. I know I can do similar thing but I have to know bundles at runtime or even build them during the same bundling process and split as separate chunks.
My inspiration is Atom plugin system but for web without file system and Node context as Atom has. I have full access to server so anything server can do over http/ws could work.
I was initially thinking about something like webpack-dev-server but I don't want to rebuild whole application. My goal is to eliminate Node runtime dependency at server because I'm using other backend language for that right now and only provide already built bundles.

Bundling Angular 2.0 source files into one vendor file for deployment

I'm starting new project which will be based on some legacy code which was written using https://github.com/linemanjs/lineman-angular-template lineman-angular-template and Angular 1.5 components
But all new stuff i want to write as Angular 2 components. And i'm looking how to
concat all source code from angular# folder into one file let's say vendor.js
Previously i saw such variant How to compile an Angular2 TypeScript application to a single file?
src="/node_modules/angular2/bundles/angular2.dev.js"
but now in node_modules/#angular there is no more bundles/angular2.dev.js
I can't use cdn for it. I need to store everything on my server.
Can you suggest me some tool or smth like that?
Angular-cli also won't work for this case.

Interchangeable configuration files in Webpack

I'm trying to bundle a react project that can run in multiple environments and needs different configurations to run on each one. I have it set up with browserify, but have recently been looking to move to webpack.
The idea goes like this: there's a js directory with a bunch of js files, of which main.js is the entry point. There is also a config folder with development.js, staging.js, production.js and so on. I am importing the configuration from all files using import config from './config'. So I want to be able to create a main.bundle.js file with all our code, and another config.js whose contents can be replaced with those of {environment}.js.
This allows us to choose the configuration for the app in deploy time, not at build time, just by copying over the contents of {environment.js}.
I have attempted to unsuccessfully use webpack's CommonsChunkPlugin, but it complains at bundle time that js/config.js is not there (obviously).
Why not make multiple builds, one with each config, and then deploy the one you want? There's different ways you could load the desired config for the build, but one very way would be to use the DefinePlugin to define constants for each environment, write a conditional against those constants to load the corresponding config, and let the Uglify plugin's dead code elimination pare down the conditional to the one valid case. I've used this approach in a number of places to handle per-environment conditionals without bloating the production code.

Categories