Angular window injecting - javascript

Is it possible prevent angular instance inject into global (window) scope when being required and bundled with webpack for example or any other module bundler?
I have found that current main javascript file in angular npm package is:
require('./angular');
module.exports = angular;
My webpack entry file contents is:
import angular from 'angular';
// my custom code goes here
So, the main webpack task is to prevent leaking variables to global scope, but if I try to log angular in Chrome DevTools like this:
console.log(angular); // => Object {version: Object, callbacks: Object}
I will see, that angular instance is injected. Any ideas to prevent this?
Additional info:
Angular.js version - 1.6.0-rc.0
Webpack version - 2.1.0-beta.27
Update.

It looks like it's hard coded into the published NPM code to assign the global Angular variable to the window object no matter what:
angular = window.angular || (window.angular = {})
So there's no direct way to prevent it from happening. You could always delete window.angular after you load it, but no promises that won't affect the library.

Related

Access webpack modules / variables from global scope

I have my react application compiled through from webpack. I'm using google recaptca's callback url like so:
<script defer src='https://www.google.com/recaptcha/api.js?render=explicit&onload=mywebpackfn'></script>
mywebpackfn is defined inside my webpack compiled js file. api.js can't find it. How can I get access to the webpack js scope from outside?
You could simply expose your function to global scope. Inside your code
if( typeof window !== 'undefined' ) { // browser env
window.mywebpackfn = yourFunction
}
Or something fancy to access global scope
// I know kung fu
(new Function('return this')()).mywebpackfn = yourFunction
Also you might want to compile your code as library https://webpack.js.org/configuration/output/#output-library
Webpack config
output: {
..
library: 'mywebpackfn',
libraryTarget: 'window'
}
If you are familiar with nodejs then you can create your node server outside of that webpack and api.js. In such a way that node server will be common to both webpack and api.js.
In that way you can export your file from webpack that will still be required by api.js by that nodejs server.
Hope this will help.
If you want to keep things controlled via webpack, rather than assign to window directly in your codebase, you can use the expose-loader
https://github.com/webpack-contrib/expose-loader
Or you can specify the output.library option of webpack which will expose the exports of your entry file as an object in global scope - you could export your callback from there

How to compile a TypeScript project to a single JS file so it is usable in browser

I have to write a Javascript SDK for a little project I am working on. To do that, I had thought of creating a TypeScript project and compiling it to a single Javascript file, so the users of my SDK could just inject that file in their web pages.
However, I just came to know that if I use import, and try to compile to a single file, then it only supports SystemJS.
So, how to compile a TypeScript project to a single JS file so it is usable in browser?
By usable in browser, I mean that if I create a class App in TypeScript, then I could do this in dev console:
var x = new App();
I have been at this for more than a hour now, and everything I have found seems to suggest that this is not possible.
Edit: This doesn't really answer my question. Like I said in the example, I need the functionality that if there is a class called App in my TypeScript project, it should be visible to the browser with the same name, so I could do var x = new App() in my dev console. (Or a user can do this in his JS file that he injects after injecting my SDK file). That answer is just telling how to create an outfile in SystemJS.
For this you can use webpack, it is a Node.JS utility that attempts to bundle Node.JS-like modules. Webpack doesn't automatically export modules to the global object, but generates (or attempts to generate) a function that replace the Node.JS's default require, which is used to execute the entry module and others, thus you can modify this function for exporting each module (or properties of each module) in the global object.
(In TypeScript, use the CommonJS module. Second, install and use the ts-loader plugin among with webpack, so you'll directly compile TypeScript from webpack.)
Maybe that applies to Webpack 2. For example, you modify the __webpack_require__ function. It is not inside the global object and thus you must interfere in the webpack's generated source code, at function __webpack_require__:
function __webpack_require__(moduleId) {
// [...] (After the `if (installedModules...) ...`)
/*
* You don't have access to the module name, so export each
* property to the browser's global object.
*/
var exports = module.exports;
for (var key in exports)
window[key] = exports[key];
}

Trying to pass gulp environment-dependent web-pack variables into angularjs app

I'm fairly new to AngularJS and gulp and webpack so excuse me if I'm not using correct terminologies. Been reading stack overflow and angularjs stuff for 2 hours and can't make the connections with what I'm reading.
I'm coming into an already developed application and trying to find the best way to include analytics API keys from a webpack plugin variables into the AngularJS app to use.
The directory is setup as such:
ng_organize
/gulp
/tasks
webpack-development.js
webpack-production.js
/util
/src
/appName
/customer
CustomerController.js
...
/home
/shop
app.js
index.js
application.js
The webpack variables in ng_organize/gulp/tasks/webpack-development.js are:
gulp.task('webpack:development', function(callback){
webpack({
context: ...
plugins: [
new webpack.DefinePlugin {
GOOGLE_ANALYTICS_KEY: 'XXX',
...
}
]
});
});
Currently, the webpack variables can be accessed in ng_organize/application.js with GOOGLE_ANALYTICS_KEY. I'm trying to access them within ng_organize/src/appName/customer/CustomerController.js.
I want to create a service to store GOOGLE_ANALYTICS_KEY (and other keys) that is dependent on the environment. Is this possible? If so, how would I go about doing it?
It turns out they are automatically included globally in your app's code, you just won't be able to call the global variables in the debugger (which was how I was testing to see if they were accessible inside the CustomerController).
GOOGLE_ANALYTICS_KEY is still accessible inside CustomerController.

Angular, third part modules and Browserify

I'm developing a little app which uses Angular and Browserify. When I declare a new module I expect to Angular be already loaded in window, so I use
var angular = window.angular
and so on. This work well, but since I'm requiring a third part module (ngReact) declared as
require('ngReact')
I get this message on the console:
WARNING: Tried to load angular more than once.
How can avoid it?

angularjs undefined main module when minifying using typescript

I am trying to minify and uglify my angularjs + typescript app using grunt-minified. Currently I am getting an error that my main module for the app is not available when I minify. I know why this is occuring due variable names no longer matching the names of the modules they reference. How would I set up annotation so angular is able to identify my main module after minification?
declare module BB {
}
module BB.MyModule {
// initialize the module
export var module = angular
// load the dependencies
.module("MyModule", [
// dependancies
]);
}
This basic setup is working fine unminified, but MyModule is not defined when I minify it. How would I go about defining for safe minification?
You have:
declare module BB {
}
Probably BB has been minified to something else. That would make module BB.MyModule be different from BB.
Solution: Your code is already safe for minification if the point where you bootstrap angular https://docs.angularjs.org/api/ng/function/angular.bootstrap is minified through the same pipeline as BB.module is passed through.

Categories

Resources