Skip to content
This repository was archived by the owner on Dec 3, 2023. It is now read-only.

Commit f3285e7

Browse files
committed
basic module parsing
1 parent d3fb355 commit f3285e7

File tree

27 files changed

+568
-5
lines changed

27 files changed

+568
-5
lines changed

.jshintrc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"curly": true,
3+
"eqeqeq": true,
4+
"immed": true,
5+
"latedef": true,
6+
"newcap": true,
7+
"noarg": true,
8+
"sub": true,
9+
"undef": true,
10+
"unused": true,
11+
"boss": true,
12+
"eqnull": true,
13+
"node": true
14+
}

Gruntfile.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
var _ = require('lodash');
3+
4+
module.exports = function (grunt) {
5+
// Show elapsed time at the end
6+
require('time-grunt')(grunt);
7+
// Load all grunt tasks
8+
require('load-grunt-tasks')(grunt);
9+
grunt.task.loadTasks('tasks');
10+
11+
// Project configuration.
12+
grunt.initConfig({
13+
jshint: {
14+
options: {
15+
jshintrc: '.jshintrc',
16+
reporter: require('jshint-stylish')
17+
},
18+
gruntfile: {
19+
src: 'Gruntfile.js'
20+
},
21+
lib: {
22+
src: ['lib/**/*.js']
23+
}
24+
},
25+
webpackScenario: _.object(_.map(grunt.file.expand({cwd:'scenarios'}, '*'), function(test){
26+
return [test, { src: ['scenarios/'+test+'/webpack.conf.js'] }];
27+
})),
28+
watch: {
29+
gruntfile: {
30+
files: '<%= jshint.gruntfile.src %>',
31+
tasks: ['jshint:gruntfile']
32+
},
33+
lib: {
34+
files: '<%= jshint.lib.src %>',
35+
tasks: ['jshint:lib', 'nodeunit']
36+
},
37+
test: {
38+
files: ['scenarios/**/*'],
39+
tasks: ['webpackScenario']
40+
}
41+
}
42+
});
43+
44+
// Default task.
45+
grunt.registerTask('default', ['jshint', 'webpackScenario']);
46+
47+
48+
};

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2014 Paul
3+
Copyright (c) 2014 Paul Thomas <[email protected]>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
21+
SOFTWARE.

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
angular-webpack-plugin
2-
======================
1+
# angular-webpack-plugin [![Build Status](https://secure.travis-ci.org/stackfull/angular-webpack-plugin.png?branch=master)](http://travis-ci.org/stackfull/angular-webpack-plugin)
32

4-
Plugin for webpack to teach it angular.js modules
3+
Makes webpack aware of AngularJS modules.
4+
5+
## Getting Started
6+
This project is just getting off the ground.
7+
8+
9+
## Release History
10+
_(Nothing yet)_
11+
12+
## License
13+
Copyright (c) 2014 Paul Thomas. Licensed under the MIT license.

lib/AngularModuleDefinition.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// © Copyright 2014 Paul Thomas <[email protected]>.
2+
// Licensed under the MIT license.
3+
//
4+
// Module definition for angular modules
5+
6+
var NullDependency = require('webpack/lib/dependencies/NullDependency');
7+
8+
function AngularModuleDefinition(range){
9+
NullDependency.call(this);
10+
this.Class = AngularModuleDefinition;
11+
this.range = range;
12+
}
13+
module.exports = AngularModuleDefinition;
14+
15+
AngularModuleDefinition.prototype = Object.create(NullDependency.prototype);
16+
AngularModuleDefinition.prototype.type = "angular module define";
17+

lib/AngularModuleDependency.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// © Copyright 2014 Paul Thomas <[email protected]>.
2+
// Licensed under the MIT license.
3+
//
4+
// Dependency definitions for angular modules
5+
6+
7+
var ModuleDependency = require('webpack/lib/dependencies/ModuleDependency');
8+
9+
function AngularModuleDependencyTemplate() {}
10+
11+
AngularModuleDependencyTemplate.prototype = {
12+
constructor: AngularModuleDependencyTemplate,
13+
apply: function(dep, source, outputOptions, requestShortener){
14+
if( !dep.range ){
15+
return;
16+
}
17+
var comment = "", content = "require(";
18+
if(outputOptions.pathinfo){
19+
comment += "/*! " + requestShortener.shorten(dep.request) + " */ ";
20+
}
21+
if(dep.module){
22+
content += comment + dep.module.id;
23+
}else{
24+
content += "!(function webpackMissingModule() { throw new Error(" +
25+
JSON.stringify("Cannot find module \"" + dep.request + "\"") + "); }())";
26+
}
27+
content += ").name";
28+
source.replace(dep.range[0], dep.range[1]-1, content);
29+
},
30+
applyAsTemplateArgument: function(name, dep, source){
31+
if( !dep.range ){
32+
return;
33+
}
34+
source.replace(dep.range[0], dep.range[1]-1, name);
35+
}
36+
};
37+
38+
function AngularModuleDependency(request, range){
39+
ModuleDependency.call(this, request);
40+
this.Class = AngularModuleDependency;
41+
this.range = range;
42+
}
43+
44+
AngularModuleDependency.prototype = Object.create(ModuleDependency.prototype);
45+
46+
AngularModuleDependency.prototype.type = 'angular module';
47+
48+
AngularModuleDependency.Template = AngularModuleDependencyTemplate;
49+
50+
51+
module.exports = AngularModuleDependency;

lib/index.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// © Copyright 2014 Paul Thomas <[email protected]>.
2+
// Licensed under the MIT license.
3+
//
4+
// Main entry point of the angular-webpack-plugin module
5+
// Defines a plugin for webpack to help it understand angular modules.
6+
7+
var path = require('path');
8+
9+
var LocalModulesHelpers = require("webpack/lib/dependencies/LocalModulesHelpers");
10+
var NullDependencyTemplate = require("webpack/lib/dependencies/NullDependencyTemplate");
11+
var NullFactory = require("webpack/lib/NullFactory");
12+
var ModuleParserHelpers = require("webpack/lib/ModuleParserHelpers");
13+
var RequireHeaderDependency = require("webpack/lib/dependencies/RequireHeaderDependency");
14+
15+
var AngularModuleDependency = require('./AngularModuleDependency');
16+
var AngularModuleDefinition = require('./AngularModuleDefinition');
17+
18+
function AngularPlugin() {}
19+
20+
module.exports = AngularPlugin;
21+
22+
23+
AngularPlugin.prototype = {
24+
constructor: AngularPlugin,
25+
26+
// This is the entrypoint that is called when the plugin is added to a
27+
// compiler
28+
apply: function(compiler){
29+
compiler.plugin("compilation", this.addDependencyFactories.bind(this));
30+
compiler.parser.plugin('expression angular', function(){
31+
return ModuleParserHelpers.addParsedVariable(this, 'angular',
32+
"require('angular')");
33+
});
34+
compiler.parser.plugin('call angular.module',
35+
this.parseModuleCall.bind(this, compiler.parser));
36+
compiler.resolvers.normal.plugin('module-module',
37+
this.resolveModule.bind(this, compiler.resolvers.normal));
38+
},
39+
40+
// This sets up the compiler with the right dependency module factories
41+
addDependencyFactories: function(compilation, params){
42+
compilation.dependencyFactories.set(AngularModuleDependency,
43+
params.normalModuleFactory);
44+
compilation.dependencyTemplates.set(AngularModuleDependency,
45+
new AngularModuleDependency.Template());
46+
compilation.dependencyFactories.set(AngularModuleDefinition,
47+
new NullFactory());
48+
compilation.dependencyTemplates.set(AngularModuleDefinition,
49+
new NullDependencyTemplate());
50+
},
51+
52+
// Each call to `angular.module()` is analysed here
53+
parseModuleCall: function(parser, expr){
54+
var mod, deps;
55+
ModuleParserHelpers.addParsedVariable(parser, 'angular',
56+
"require('angular')");
57+
switch(expr.arguments.length){
58+
// A single argument is the equivalent of `require()`
59+
case 1:
60+
mod = parser.evaluateExpression(expr.arguments[0]);
61+
return this._addDependencyForParameter(parser, expr, mod);
62+
// 2 arguments mean a module definition if the 2nd is an array.
63+
case 2:
64+
mod = parser.evaluateExpression(expr.arguments[0]);
65+
// TODO: should we check the module name?
66+
this._addModuleDefinition(parser, expr, mod);
67+
deps = parser.evaluateExpression(expr.arguments[1]);
68+
if( deps.items ){
69+
return deps.items.every(
70+
this._addDependencyForParameter.bind(this, parser, expr));
71+
}
72+
return this._addDependencyForParameter(parser, expr, mod);
73+
// 3 arguments must be a module definition
74+
case 3:
75+
mod = parser.evaluateExpression(expr.arguments[0]);
76+
// TODO: should we check the module name?
77+
this._addModuleDefinition(parser, expr, mod);
78+
deps = parser.evaluateExpression(expr.arguments[1]);
79+
return deps.items.every(
80+
this._addDependencyForParameter.bind(this, parser, expr));
81+
default:
82+
console.warn("Don't recognise angular.module() with " +
83+
expr.arguments.length + " args");
84+
}
85+
},
86+
87+
resolveModule: function(resolver, request, callback){
88+
var fs = resolver.fileSystem;
89+
var i = request.request.indexOf(".");
90+
if(i < 0) {
91+
// Try resolving a file of the form module/module
92+
return resolver.doResolve("file", {
93+
path: request.path,
94+
request: path.join(request.request, request.request),
95+
query: request.query
96+
}, callback, true);
97+
}
98+
// Try treating `.` as a path separator
99+
var moduleName = request.request.substr(0, i);
100+
var remainingRequest = request.request.substr(i+1);
101+
var modulePath = resolver.join(request.path, moduleName);
102+
fs.stat(modulePath, function(err, stat) {
103+
if(err || !stat) {
104+
if(callback.log){
105+
callback.log(modulePath + " doesn't exist (ng module as directory)");
106+
}
107+
return callback();
108+
}
109+
if(stat.isDirectory()) {
110+
var types = request.directory ? "directory" : ["file", "directory"];
111+
return resolver.doResolve(types, {
112+
path: modulePath,
113+
request: remainingRequest,
114+
query: request.query
115+
}, callback, true);
116+
}
117+
if(callback.log){
118+
callback.log(modulePath + " is not a directory (ng module as directory)");
119+
}
120+
return callback();
121+
});
122+
},
123+
124+
125+
_addModuleDefinition: function(parser, expr, mod){
126+
var dep = new AngularModuleDefinition(mod.range);
127+
dep.loc = expr.loc;
128+
dep.localModule = LocalModulesHelpers.addLocalModule(parser.state, mod.string);
129+
parser.state.current.addDependency(dep);
130+
return true;
131+
},
132+
133+
// A dependency (module) has been found
134+
_addDependencyForParameter: function(parser, expr, param){
135+
if( param.isConditional() ){
136+
// TODO: not sure what this will output
137+
parser.state.current.addDependency(
138+
new RequireHeaderDependency(expr.callee.range));
139+
param.options.forEach(function(param) {
140+
var result = parser.applyPluginsBailResult("call require:commonjs:item",
141+
expr, param);
142+
if(result === undefined) {
143+
throw new Error(
144+
"Cannot convert options with mixed known and unknown stuff");
145+
}
146+
});
147+
return true;
148+
}
149+
if( param.isString() ){
150+
var dep;
151+
var localModule = LocalModulesHelpers.getLocalModule(parser.state,
152+
param.string);
153+
if( localModule ){
154+
//dep = new LocalModuleDependency(localModule, expr.range);
155+
//dep.loc = expr.loc;
156+
//parser.state.current.addDependency(dep);
157+
return true;
158+
}
159+
dep = new AngularModuleDependency(param.string, param.range);
160+
dep.log = expr.loc;
161+
parser.state.current.addDependency(dep);
162+
return true;
163+
}
164+
parser.applyPluginsBailResult("call require:commonjs:context", expr, param);
165+
return true;
166+
}
167+
168+
};

package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "angular-webpack-plugin",
3+
"version": "0.0.0",
4+
"main": "lib/index.js",
5+
"description": "Makes webpack aware of AngularJS modules.",
6+
"homepage": "https://github.com/stackfull/angular-webpack-plugin",
7+
"bugs": "https://github.com/stackfull/angular-virtual-scroll/issues",
8+
"author": {
9+
"name": "Paul Thomas",
10+
"email": "[email protected]",
11+
"url": "http://blog.stackfull.com/"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/stackfull/angular-virtual-scroll.git"
16+
},
17+
"licenses": [
18+
{
19+
"type": "MIT"
20+
}
21+
],
22+
"peerDependencies": {
23+
"webpack": "~1.0.0"
24+
},
25+
"devDependencies": {
26+
"grunt-contrib-jshint": "~0.7.0",
27+
"grunt-contrib-watch": "~0.5.0",
28+
"load-grunt-tasks": "~0.2.0",
29+
"time-grunt": "~0.2.0",
30+
"jshint-stylish": "~0.1.3",
31+
"grunt-mocha-test": "^0.9.4",
32+
"coffee-script": "^1.7.1",
33+
"webpack": "~1.0.0",
34+
"async": "^0.2.10",
35+
"lodash": "^2.4.1",
36+
"underscore.string": "^2.3.3"
37+
},
38+
"scripts": {
39+
"test": "grunt webpackScenario"
40+
}
41+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
angular.module('dependency', []);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// 1 dep
2+
angular.module('myModule', ['dependency']);

0 commit comments

Comments
 (0)