Import dynamically generated script from html file with webpack 2 - angularjs

I'm in the process of migrating to webpack using typescript and I have some script dynamically generated into my index.html like so
<script>(function(modules) { code inside ... })</script>
How would I import code (pretty straight compiled typescript to javasript code) from this script into my main.ts file (the entry point)? For example
import whateverFunction from 'index.html'
Of course that doesn't work but I would love to see the right way to implement it. Thanks in advance.

If you defined a variable on index.html and you want to use it in typescript you need to do this:
declare var prod: boolean;
declare var version: string;
export class whateverName{
}
you should use the same name that used in index.html file.

Related

How to use global variables in Storybook with React

I found this answer, but I am not able to solve the issue with it.
The component I trying to load in Storybook depends on a global variable that is injected via a CDN in index.html.
To access the variable in the component I added this comment at the top of the file
/*global <variable name>*/
It's working fine in the React app, but Storybook throwing this error: <variable name> is not defined.
I tried adding that comment at the top of the stories.js file and at the top of the config file. - no luck.
The URL for the CDN is in an env file. From looking at this doc I tried adding a second script in the HTML file with an env variable that is prepended with STORYBOOK_. That didn't work either.
Any ideas on what I can do to get past this?
I've solved this by adding custom head tags: https://storybook.js.org/docs/configurations/add-custom-head-tags/#docs-content
Then adding my global variables there, for example:
// preview-head.html
<script>
var foo = bar
</script>

Angular cli: include angularjs component styles in ngUpgrade hybrid project

Now I'm moving to a hybrid angular/angularjs project. But I stuck with import styles problem.
For example, my simple angularJs component:
import template from './simple.html';
import controller from './simple.controller.js';
import './simple.less'; // <-- Look at
export const SimpleComponent = {
template,
controller
};
I expect that styles will be extracted and included in the project.
Before I switched to the angular-CLI all magic works because of 'MiniCssExtractPlugin'.
If I create angular components:
#Component({
selector: 'app-simple',
templateUrl: './simple.html'
styleUrls: ['./simple.less']
})
All styles add correct. The same, if I it with angular.json ->
(path) projects.projectName.architect.build.options.styles
"styles": [ "src/assets/styles/index.less" ]
Now I suggest 2 ways to solve the problem (first doesn't work, second will be in a pinch):
1) Add "extractCss":true rule in angular.json -> projects.projectName.architect.serve.options. But it doesn't work.
I create issue on github about "extractCss" option.
But maybe I don't understand what exactly "extractCss" option means, and delegate 'MiniCssExtractPlugin' plugin functionality to it?
2) Create 'app.less' in 'src/app' folder and add all component styles to it. After that include it to 'angular.json' -> "styles": ["src/app/app.less"]. But it takes a lot of overhead because we have a lot of components =)
Thank you for attention =)

Import angularjs modules with webpack

We've got a rather large project written in angularjs and are moving gradually to angular 4. The plan is to first rewrite everything to typescript + angularjs components. We've set up an empty angularjs+webpack+typescript project and are converting legacy angularjs modules to typescript. This works fine, but because of the size of the project we would like to add the 'old' angularjs modules for now and execute those scripts so we have a full working project.
I haven't found a way to make this work. So basically we've got (I've omitted some details for brevity):
app.module.ts:
import * as angular from 'angular';
import { moduleName as module1 } from './app/converted.module1';
import { moduleName as module1 } from './app/converted.module2';
export const moduleName =
angular.module('application', [
module1,
module2,
'legacy_module_3',
'legacy_module_4'
]).name;
So module1 and module2 are already converted typescript modules. Module 3 and module 4 not. We don't want to convert those yet but do want to reference them. Lets say those modules reside in '/frontend/module3.js' and '/frontend/module4.js', how would I make this work (executed js code) with webpack?
Consider just biting the bullet and doing minimal conversion on everything in one go.
I just went through a similar exercise converting an existing angularjs project to use webpack. The conversion needed for each module is small enough that I just converted all of the modules. So where we had:
angular.module('somemodule').controller(function(){ ... })
I changed those to:
export default function SomeController() { ... }
and the module declaration files all now look like:
import SomeController from './some.controller'
export default angular.module('SomeModule', [])
.controller(SomeController)
.name;
Then the top level:
import SomeModule from './some/module'
angular.module('app', [ SomeModule ]);
It took a little while, but as the changes are largely mechanical I was able to just work systematically through the entire application. Some sub-folders were just using the 'app' module name, so I added a 'module.js' file in each folder with an appropriate module name, but otherwise there weren't any real changes to be made.
I also had to change all of the template urls into imports and I imported the '.scss' file into the top level of the app (though that wasn't really required).
Next step will be to convert controllers and directives to components, but that should be pretty straightforward now.
You've got to export each one of your modules and then import them in your app module. Notice the following example:
//..import your other ts modules
import module3 from './frontend/module3.js' //This have to be relative path
import module4 from './frontend/module4.js'
export const moduleName =
angular.module('application', [
module1,
module2,
module3.name ,
module4.name
]).name;
Also notice that your old js modules should export a module:
e.g. filters module.
import angular from 'angular';
import myNiceFilter from './myNiceFilter.filter';
var filters = angular.module('filters',[]);
filters.filter('myNiceFilter', myNiceFilter);
export default filters;

#section syntax instead of requirejs or browserify for angularjs application

I understand that requirejs and browserify can load my files dependent on its current context, and that it is amazing. I would really prefer to use the #section sections syntax that the razor engine uses. Was just wondering if there is a way to implement this into a typescript / angularjs application.
for example
index.html
#renderSection scripts;
// which could turn into something like
<script data-render="scripts"></scripts>
// the app.run() could declare all the scripts that will be needed on every
// page view
view.html
<script ng-section-repeat="injected in injection"></script>
// the ng-section-repeat is basically taking all the items in the
// typescript constructor and then finding out which ones are needed for
// that view.
I like the idea injecting application file dependencies in the view , without a configuration file and all the added extras that comes with the loaders.
I just want to easily define what files are needed in the actual view and get them loaded, with angular's dependency injection handling the dependency itself.
If you are handling all your dependencies with $inject then , as far as i can tell, dependency is technically already setup in the controllers, all one would need, is to load this as it is called. Which could even eliminate the need for the #section scripts completely
Update:
What i have done to sort of replicate the module loaders is to just use gulp-concat and define the file order in my gulp.config.js and then pass it to the gulp-src before running $.concat .this allows me to have the files in the gulp steam , in dependent order . They are however loaded on the first load. With gulp-uglify the files are tiny ( its now at 566Kb with 16 external libraries loading in 69ms . To put that into perspective it takes 209ms to load one google font ).
I dont know maybe i am not understanding browserify correctly but i honestly struggle to see the need for it, its seems extremely convoluted for something so simple
It is possible using external modules and an injector to do what you asked for:
I just want to easily define what files are needed in the actual view
import {UserFactory} from 'models/userFactory';
import {UserValidator} from 'models/userValidator';
import {Inject} from 'angular2/di';
and get them loaded, with angular's dependency injection handling the dependency itself.
Note: My example uses angular 2.x because I less familiar with angular 1.x and I'm sure you can do something really similar...
class SomeComponent {
userName: string;
userRating: number;
rating: number;
constructor(
#Inject(UserFactory) UserFactory
#Inject(UserValidator) UserValidator
)
{
this.UserFactory = UserFactory;
this.UserValidator = UserValidator;
}
}
Then you can use Browserify to create a bundle.js file that can be executed in a web browser.

How to add a template to body in Meteor inside a package

I have this template:
<template name="sample">
<h1>Sample</h1>
</template>
Inside a Meteor app I can add this to body this way (as a partial):
{{> sample}}
It works. I've even tested to call Template.sample(); inside browser console and it works.
When I move this inside my package (i.e. a sample.html file inside my package folder) the template seems to disappear: I get Template.sample() is not a function whenever I call the function and I am not even able to render it as a partial.
I have a package.js with this code (and obviously the package is correctly loaded inside my app through packages file in .meteor):
Package.on_use(function (api) {
api.add_files(['sample.html', 'sample.js'], 'client');
});
Why this doesn't work?
How can I append a (reactive) Template to body from my package?
Solved! Add this line:
api.use(['templating'], 'client');
it is also important to include the html file before the js
api.add_files("client/sampleTemplate.html", "client");
api.add_files("client/sampleTemplate.js", "client");
Include in file packages.js of package
before
api.use('meteor-platform');
api.use('ui');`
after
first ".html" files, after ".js" files
api.addFiles('filename.html','client');
api.addFiles('filename.js','client');`

Resources