Code Monkey home page Code Monkey logo

closure-compiler-angular-bundling's Introduction

closure-compiler-angular-bundling's People

Contributors

alexeagle avatar jeffbcross avatar jkuri avatar robwormald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

closure-compiler-angular-bundling's Issues

ngc compile files inside src folder

I solved this like this:

tsconfig.json(this put in root folder):

{
  "compilerOptions": {
    "target": "es6",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": false,
    "noImplicitAny": true,
    "declaration": true,
    "experimentalDecorators": true,
    "outDir": "./built"
  },
  "angularCompilerOptions": {
   "genDir": "built",
   "annotationsAs": "static fields",
   "annotateForClosureCompiler": true
 },
 "exclude": [
     "vendor",
     "node_modules",
     "built",
     "dist"
 ]
}

closure.conf this changed:

--js built/**/**.js
--entry_point=./built/src/bootstrap

bootstrap.ts this changed:

import {AppModuleNgFactory} from '../built/src/app.module.ngfactory';

If there is some better way to solve this let me know

latest: broken by closure ES2015 module support

I just pushed my latest WIP, using a PR in Angular that avoids having to use any custom versions. Maybe we can get this working with no hacks....

Current issue is:

built/Basic.js:1: ERROR - required "module$$angular$core" namespace never provided
import { Component, Injectable } from '@angular/core';
^

but node_modules/@angular/core/index.js exists and is passed to the compilation.

You can repro with the simple steps in the README.md

@MatrixFrog if you have a minute, can you help me understand how the names of input files to the compilation get mapped to valid paths the ES2015 imports can use?

Consider process_common_js_modules

I did an experiment today using process_common_js_modules to integrate the default commonjs build of rxjs with the sample app.

There is a bug in the current build of Closure compiler that prevents this from working. However the bug seems to be fixed in Head, so I built a new version of Closure from source.

Not sure what you guys think about going in this direction vs waiting for an ES2015 build?

What I like about process_common_js_modules is that it may at least be a solution for future commonJS libs that we may encounter. It also solves the issue of having to add an extraneous export statement to the rxjs modules to make it work with ES2015.

There is no impact to imports in user code. We can still use regular ES2015 import statements since Closure seems to do the conversion.

There is one issue that I encountered in a rxjs module called root.js

"use strict";
/**
 * window: browser in DOM main thread
 * self: browser in WebWorker
 * global: Node.js/other
 */
exports.root = (typeof window == 'object' && window.window === window && window
    || typeof self == 'object' && self.self === self && self
    || typeof global == 'object' && global.global === global && global);
if (!exports.root) {
    // Comment out this thow and the app works
    throw new Error('RxJS could not find any global context (window, self, global)');
}
//# sourceMappingURL=root.js.map

The following code is for some reason compiled down to a standalone throw. If I comment out the throw in the rxjs file it works though.

I guess this code is not Closure safe. Not sure why it needs this throw. Wouldn't one of these variables always be defined?
(e.g. root = window || global || self).

I don't see the need for this throw, but I might be missing something as I only looked at it briefly.

Anyway. I have a working sample in my fork if you are interested: https://github.com/thelgevold/closure-compiler-angular-bundling-old/tree/rxjs-commonjs

Since it's a bit of a pain to do Closure releases, I have included the new Closure jar file in my branch.

Here is the commit diff: thelgevold@15a52a7

Doesn't work with latest closure compiler

Upgrading from v20170409 to v20170423 breaks the Angular example:

Release notes: https://github.com/google/closure-compiler/wiki/Releases#april-23-2017-v20170423
Broken build:
https://circleci.com/gh/alexeagle/closure-compiler-angular-bundling/82

node_modules/@angular/core/@angular/core.js:5607: ERROR - variable System is undeclared
        return System.import(module)
               ^^^^^^

node_modules/@angular/platform-browser/@angular/platform-browser.js:3091: ERROR - variable Hammer is undeclared
        const /** @type {?} */ mc = new Hammer(element);
                                        ^^^^^^

node_modules/moment/moment.js:8: ERROR - variable module is undeclared
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
                                          ^^^^^^

node_modules/moment/moment.js:9: ERROR - variable define is undeclared
    typeof define === 'function' && define.amd ? define(factory) :
           ^^^^^^

node_modules/moment/moment.js:399: ERROR - variable require is undeclared
                require('./locale/' + name);
                ^^^^^^^

node_modules/rxjs/util/root.js:8: ERROR - variable global is undeclared
else if (typeof global == 'object' && global.global === global) {
                ^^^^^^

cc @StephenFluin

package.json issue

"rxjs-es": "^5.0.0-rc"

No compatible version found: rxjs-es@^5.0.0-rc

Property naming idea(s)

This is an issue to kick around ideas for property naming (Closure renaming...) of properties in objects exposed by Components to templates.

I'm not a fan of a mechanism to further automate forcing quoted property identifiers that don't get renamed - because:

  • That gives away optimization
  • It kind of breaks JavaScript (which TS is an extension of), which makes a.x == a['x']
  • Changing my Component and Service code to use more quoted property names is ugly, and thus creates resistance to the ABC future.

Rather, I'd like Angular + tsickle + CC to meet the following contract:

IF, as a developer, I:

  • use typed data structures for any data exposed by a component to a template
  • turn TypeScript type safety (-ish) as high as it will code, with the new string option
  • use consistently, idiomatically unquoted field identifiers

THEN,

  • Angular + tsickle will generate enough detailed typing that CC is fully aware of these (record?) types
  • Angular compiler will generate non-quoted-style access in compiled templates
  • ... so that CC can see types across the whole code base (template, components, services, etc.)
  • ... and can perform aggressive renaming without breaking anything

Is this feasible? Desirable?

cc @alexeagle @thelgevold

improved results

Hi @alexeagle, thank you for sharing this.
I improved results a bit for working sample and getting

-rw-r--r--  1 jan  staff   110K Dec 18 07:51 dist/bundle.js
-rw-------  1 jan  staff    30K Dec 18 07:51 dist/bundle.js.brotli
-rw-r--r--  1 jan  staff    34K Dec 18 07:51 dist/bundle.js.gz

here's a link to demo repository: https://github.com/jkuri/angular-closure-compiler

Use lodash

I recently started with the list of most depended on NPM packages. This list is mixed: includes the vast numbers of server-side only packages, whereas what I really want to know is: what packages are most frequently used from browser-based code?

https://www.npmjs.com/browse/depended

Still, the number one entry is lodash, and it is very commonly used from browser-based applications.

I briefly tried integrating with with (my fork of) this application, but after hitting snags, set that aside to try a nearly trivial case instead:

https://github.com/kylecordes/closure-lodash

The entire source code I'm trying to make work:

import { flatMap } from 'lodash-es';   // or lodash, not picky

const x = ['a', 'b', 'c'];
console.log(flatMap(x, item => [item, item]));

I hit snags, probably because I don't yet know Closure well enough. (I worked with it a bunch in the past, but almost always as a downstream tool consuming code that came from ClojureScript, itself designed to emit code that Closure will accept. Aside from the homonymic names, it all works very nicely.)

This item is a kind of tracking issue, if I'm successful getting it running standalone then I will try to get it running with angular, and then after that, here.

Angular + Closure 3p Library consumption

Consuming libraries with Closure can be nontrivial. :-)

Here is an issue/thread to try to figure out how to do so most effectively. There seem to fundamentally be (at least) a few ways to consume a given library. Roughly they break down to:

  • Consume it as it is
  • Repackage it for better use from Closure, then urge upstream providers to include such results in their packages

Setting aside the social challenge of the latter for a moment, here are some thoughts on ways libraries can be packaged to make Closure consumption easier or harder.

CommonJS

Consume library code typically consumed with other tooling - which usually means CommonJS. Closure has a feature (but with open issues?) to help with this.

Advantages:

  • In theory this should "just work" with the whole ecosystem right away.

Disadvantages:

  • Obtains the least possible benefit from Closure. Certainly no ADVANCED_OPTIMIZATIONS of this code.
  • Externs files are almost never packaged with off-the-shelf libraries in the ecosystem, so we'll have to get those somewhere else anyway in most cases.

TypeScript code

It would be quite nice if software written in TypeScript was distributed in NPM in TypeScript. Another other things, such code could be easily passed through tsickle then Closure for optimal results.

Advantages:

  • The code would be passed through the exact same version of Tsickle and TSC as the consuming application
  • The code would benefit from further improvements to Tsickle/TSC

Disadvantages:

  • Possibly slower, since the whole consumer community is recompiling these libraries instead of using compiled output.

Flat ES2015-in-ES2015 with Closure JSDocs

Consume library code specifically packaged this way. This is how Angular is packaged, and many of us think this is the package format of the future for arbitrary code in NPM.

Advantages:

  • Works well with Closure
  • Works well for everything else also - i.e. Webpack, Rollup
  • This is probably the future, at least my best guess of the future

Disadvantages:

  • So far, Angular is the only thing packaged this way. (Update: also Material - so it's more correct to say that so far only the Angular team is packaging things this way.)
  • So far, minor efforts to nudge other libraries to consider this have been unsuccessful.
  • There is not yet an official standard way to label these in an NPM package; Angular uses "es2015".
  • Some node traditionalists may disagree that this is the future.

(Incidentally, I have shipped a way of consuming these with Rollup: https://www.npmjs.com/package/rollup-plugin-node-resolve-angular )

Specific RxJS thoughts

RxJS is at the forefront of the importance of working out the most effective library packaging and consumption, because it is a hard requirement of every Angular application. The specifics around RxJS have been written about and other issues in this repo and elsewhere, at the moment the most irritating one is that there is a Closure bug which breaks the import "rxjs/add/blah" pattern. That is likely moved in the near future though.

Special treatment for top-tier Angular-centric libraries?

It's possible that the answer to what kind of packaging make this the most sense, varies greatly between the top couple of dozen libraries used with Angular and the rest of the ecosystem. For example, offhand it seems extremely justifiable for Material to ship FESM with Closure JSDocs, while not justifiable for the 10,000th most popular JS library to even know Closure exists.

There may be an opportunity for the Google developed key libraries like Material to lead the way here.

What's next

One next action is for those of us inside Google and outside, who are tinkering with Closure with Angular, to pick up code that has third-party library requirements, hack away and get it to run, and raise issues for anything that requires special one-off treatment.

cc @alexeagle @thelgevold

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.