rquadling / grunt-html2js Goto Github PK
View Code? Open in Web Editor NEWGrunt plugin for converting AngularJS templates to JavaScript
License: MIT License
Grunt plugin for converting AngularJS templates to JavaScript
License: MIT License
Hey @karlgoldstein !
A few days ago I thought it could be a good thing to extract the main logic out of grunt-html2js and publish it as a standalone node module. The grunt task would rather be a wrapper to work with grunt.
Why? Because we now also have the gulp task runner and it could be a cool thing to have html2js in that env too :) wdyt?
As Jade is now deprecated as of grunt-html2js 0.4.0, Jade support will be removed in the next release.
After the last npm release of 0.5.1 you updated the package.json to fix some security vulnerabilities.
Can you please release this version?
Thanks,
Stefan Seide
html file:
<div>
<div ng-class='"bsp-alert-" + (type || "warning")'></div>
</div>
without collapseWhitespace option defined results in:
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/alert/alert.html",
"<div>\n" +
"<div ng-class='\"bsp-alert-\" + (type || \"warning\")'></div>\n" +
"</div>");
}]);
with collapseWhitespace=true:
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/alert/alert.html",
"<div><div ng-class=\"\\\"bsp-alert-\\\" + (type || \\\"warning\\\")\"></div></div>");
}]);
with collapseWhitespace=false:
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/alert/alert.html",
"<div>\n" +
"<div ng-class=\"\\\"bsp-alert-\\\" + (type || \\\"warning\\\")\"></div>\n" +
"</div>");
}]);
please notice incorrect double escaping of '' in ng-class="\"bsp-alert-\"
quoteChar
works only inside the module. Module is using single quotes no matter what settings you have.
Example:
quoteChar: '\''
:
angular.module('moduleName.Templates', []).run(['$templateCache', function($templateCache) {
$templateCache.put('templates/example.html',
'<h1>Heey</h1>');
$templateCache.put('templates/example2.html',
'<h1>Heey 2</h1>');
}]);
and quoteChar: '"'
:
angular.module('moduleName.Templates', []).run(['$templateCache', function($templateCache) {
$templateCache.put("templates/example.html",
"<h1>Heey</h1>");
$templateCache.put("templates/example2.html",
"<h1>Heey 2</h1>");
}]);
Also, any chance you could add option to wrap everything with IIFE? I know you can use fileHeaderString
/ fileFooterString
but it won't indent the contents.
Hi,
Ive been using html2js for a while, really awesome. However I noticed a bug a few days back that I tracked down to html2js.
the angularjs ng-pattern directive stops working correctly. The behavior is really wierd and the regex doesnt match to what it should. I havent digged deeper into it.
What I do know is that when I disable html2js and run the templates as noraml html files the ng-pattern starts working like a charm.
I have tried this with both version 0.1.3 and 0.1.6, both fails.
I have a stackoverflow question on this for more information.
http://stackoverflow.com/questions/18397718/angularjs-ng-pattern-wierd-behavior-regex
Can anyone anyone confirm this?
If in the src attribute array, the full path to a file is given, and that file doesn't exist, right now it just continues without any errors or warnings.
It should throw an error if a specific file isn't found.
grunt-html2js has a dependency for jade ^1.3.1 which now deprecated:
npm WARN deprecated [email protected]: Jade has been renamed to pug, please install the latest version of pug instead of jade
Anyway to use ng-include for templates that have been processed by html2js?
At this moment the use strict
lives inside the module, I think it will be better if this going to outside.
Is there any specific reason to stay inside the module?
Example with IIFE
(function() {
'use strict';
angular.module('xx.chip.tmpl', ['bb/chip.html']);
angular.module('xx/chip.html', []).run(['$templateCache', function($templateCache) {
}]);
}());
The currently required version of jade in turn requires an outdated version of acorn, which has a regex that throws a Range out of order in character class
error, causing me to be unable to run grunt.
Currently the converter strips line feeds from templates. This breaks
formatted text in templates.
I'm getting this error while loading grunt tasks:
DEBUG: ERROR in file: D:\demo\node_modules\grunt-html2js\node_modules\jade\node_modules\transformers\node_modules\uglify-js\src\utils.js
/ Error: ENOENT, no such file or directory 'D:\demo\node_modules\grunt-html2js\node_modules\jade\node_modules\transformers\node_modules\uglify-js\src\utils.js'
As is commonly done in jade
, I typically have my mixins put in a subfolder, which just contain mixins, these mixins then get mixed in by the parent folder. An example mixin is something like this
mixin awesomeMixin
#someId.thisIsAnAwesomeMixin
Assuming a .jade
file will only contain the above (i.e. only mixins), the resulting template will be an empty string.
Long story short, should there be an option where if a resulting template is empty (i.e. jade
file only contains mixin
s), then grunt-html2js
wont create an angularModule for that .jade
file at all?
When modifying the base option to add the 'app' folder intead of the default 'src', the plugin doesn't find any files specified by 'src' option in the main section.
html2js: {
options: {
base: 'app',
useStrict: true,
module: 'angTestingApp'
},
main: {
src: ['views/*.html'],
dest: 'scripts/templates.js'
}
}
I'm trying to follow the LIFT principle by organizing my code by feature and not by component type.
This:
src/
fruits/
fruits.controller.js
fruits.service.js
fruits.html
vegetables/
vegetables.controller.js
vegetables.service.js
vegetables.html
vs. this:
src/
controllers/
fruits.controller.js
vegetables.controller.js
services/
fruits.service.js
vegetables.service.js
templates/
vegetables.html
fruits.html
And I would like my template modules to reflect the filename only and not the path.
Not this:
angular.module('templates-all', ['fruits/fruits.html', 'vegetables/vegetables.html']);
but, simply this:
angular.module('templates-all', ['fruits.html', 'vegetables.html']);
Using the base option, I could strip the prefix, but only if the prefix is the same for all templates, which it's not, since my templates are all in different folders. I would even settle for this, just as long as they were all uniform:
angular.module('templates-all', ['templates/fruits.html', 'templates/vegetables.html']);
How can I discard the path name, or unify the path for template files that exist in many different folders? The rename function allows me to do this:
html2js: {
options: {
rename: function (moduleName) {
return moduleName.replace('./src/templates/', '');
}
}
}
But, because my templates are in different folders, I would need to check for each folder, and add a new case each time I add a new folder:
html2js: {
options: {
rename: function (moduleName) {
swith(moduleName) {
case './src/fruits/fruits.html':
return moduleName.replace('./src/fruits/'. '');
break;
case './src/vegetables/vegetables.html':
return moduleName.replace('./src/vegetables/', '');
...
}
}
}
Is there a better way to do this? If the path and filename were provided separately, I could simply discard the path:
html2js: {
options: {
rename: function (path, filename) {
return filename;
}
}
}
Please?
one page html and no server
Amongst other things, the collapse of white space in attributes would be supported.
Hi,
we had the problem in our project that the build never ends because the task "grunt-html2-js" seems to "hang". I could trace back the problem to an HTML file where the developer made a mistake by using one double quote to much. I set up an example project to reproduce the issue.
This is my package.json:
{
"name": "testApp",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "XXX",
"license": "ISC",
"dependencies": {
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-html2js": "^0.3.0",
"grunt-init": "^0.3.2"
}
}
and my gruntfile.js:
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
html2js: {
options: {
module: 'testApp-templates',
base: 'app',
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
},
main: {
src: ['app/components/**/*.html'],
dest: 'dist/templates.js'
}
}
});
grunt.loadNpmTasks('grunt-html2js');
grunt.registerTask('default', ['html2js']);
};
Then I added in the folder app/components/html/testComp.html the buggy HTML code (the unnecessary double quote is at the end of the first line):
<div class="col-sm-4" as-sortable="dragControlListeners" ng-model="itemsZiele" style="min-height:250px; border-right-style: solid;"">
</div>
When I now start grunt I have the same problem, that the task never ends.
My expactation would be that the task should crash with an parser error or give a warning.
It would be quite useful to support something like node-glob / minimatch style expansion for the base
option similar to http://gruntjs.com/configuring-tasks#globbing-patterns
E.g. The following would create a cache reference to "slider-template.html"
instead of "angular-slider/slider-template.html"
...
html2js:
vendor:
options: base: "components/**/"
files:
".tmp/templates/vendor.js": [ "components/angular-slider/slider-template.html"]
...which is how the template is being loaded in the angular-slider library, for example.
Counter is displaying number of files
options in Gruntfile.js
not the actual number of .html
files converted. I will try to send PR soon.
This is the structure of my folder:
-index.html
-Gruntfile.js
-views (directory)
-js (directory)
-controllers (directory)
-directives (directory)
-filters (directory)
-app.js
-routes.js
Given the path relation between my views and my "index.html", all views should be called liked this:
templateUrl: 'views/some-view.html'
And that is exactly how I call them from my "routes.js" and in controllers.
It works as expected.
With that said, now I'm trying to use "grunt-html2js".
I've tried the following cases in my Gruntfile.js
Case 1:
html2js: {
options: {
module: 'myApp.templates',
},
main: {
src: ['views/*.html'],
dest: 'views/all-views.js'
}
},
Case 2:
src: ['views/*.html'],
dest: 'all-views.js'
Case 3:
src: ['views/*.html'],
dest: 'build/all-views.js'
And, in all of the cases, the result is that the name of the generated modules starts with "../"
, eg:
angular.module('myApp.templates', ['../views/some-modal.html', '../views/other-modal.html', .... etc
As written before: I don't need those two dots!
Question: ...how can I configure "grunt-html2js" correctly?
Just in case that's interesting for someone, I had the need to use the plugin with vanilla javascript:
https://github.com/soundstep/grunt-html-convert
It is a direct fork but I renamed it so people can get it easily, hope that's ok.
I explained that in the readme, with a link to your repo.
Here is what I've added:
Prefix and suffix is useful if you want to wrap the generated javascript in require.js or another function.
Romu
Hey guys....something is not working as expected in the process option! I have two tasks app_build and app_compile set like this:
html2js: {
app_build: {
src: [ '<%= app_files.atpl %>' ],
dest: '<%= build_dir %>/templates-app.js',
options: {
base: 'src/app',
process: {
title: 'Build Title'
}
}
},
app_compile: {
src: [ '<%= app_files.atpl %>' ],
dest: '<%= compile_dir %>/templates-app.js',
options: {
base: 'src/app',
process: {
title: 'Compile Title'
}
}
}
}
And in some of my *.tpl.html file i have this kind of code:
<h1> <%= title %> </h1>
But when i run the build and compile tasks nothing is displayed in the h1 tag!! What do i want to achieve is to process the title string based on type of building (build or compile)!! Is there something that i missing?
Thanks to all!
I'm wondering if it would be possible to have a option for minifying the HTML. What I mean is just remove the excess whitespace. My template files are nicely indented for my sake, but I would really love if the final product has none of that indentation in it.
When you have template that contains Mac-style (\r) newlines, it generates broken javascript. I've seen it with misconfigured git.
When there are alone \r's, they are mistakenly converted to newline and not escaped.
Example (with newline chars visible):
abc\r\r\n
def
creates
"abc
\n" +
"def"
Using the default htmlmin options from the example:
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
and using this or any similar expression in a template.
{{foo.length < 5 ? 'bar' : 'baz'}}
I get Error: Parse Error: <
Disabling individual htmlmin attributes doesn't seem to help
Would be great if there was an configuration option for output wrapped in a AMD pattern. Maybe it is already there...
(function (define, angular) {
'use strict';
define([], function () {
var moduleName = 'templates/helloworld.tpl.html';
angular.module(moduleName, []).run(['$templateCache', function($templateCache) {
$templateCache.put('moduleName',
'<div>TEMPLATE MARKUP</div>');
}]);
return moduleName;
});
})(define, angular);
I was wondering if there is an option (or if you would be open to a pull request to include this option) for adding the original filename as a comment at the top of each template.
We have a few pages with between 5 and 10 templates repeated and i think it would be useful to see these comments similar to ng-repeat and ng-switch.
I'm having trouble reloading the html2js produced template file when an html file is changed. I'm modifying a relatively standard (though a bit old) Yeoman generated gruntfile. Here's my html2js config, and a portion of the watch config. I am simply not getting the resulting ptsd_template_cache.js fille to reload upon change in any component html file. I'm assuming I've got a config problem. Can I trouble you to assist?
Thanks!!
html2js: {
options: {
base: 'app',
module: 'ptsd.templates',
singleModule: true,
useStrict: true,
watch: true
},
main: {
src: ['app/views/*.html'],
dest: 'app/scripts/templates/ptsd_template_cache.js'
}
},
watch: {
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
}
Hello everyone,
I've been trying to add a feature to a fork of this lib and I can't seem to get debugger statements inside of tasks/html2js.js to break.
I've tried various methods
node-debug $(which grunt) html2js
running node-inspector and then
node --debug-brk $(which grunt) html2js
I have managed to make it break on a debugger statement once but couldn't reproduce it.
I have had success in debugging other grunt tasks but not this one. It's as if this task is run in a separate node process that doesn't have the debug flag on.
Cheers in advance
I mean, my Gruntfile.js like follow:
html2js: {
dist: {
options: {
base: '.'
},
files: [{
expand: true,
src: ['views/ui-bootstrap-tpls/*.html'], /*** note this path ***/
ext: '.html.js'
}]
}
}
And then output
/*** note the path ***/
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/alert/alert.html",
"/* my own template */ ");
}]);
I have two completely different templates with differing options. And this structure works for most other grunt tasks. I get "Successfully converted 0 html templates to js" every time. Any help would be greatly appreciated. I'd rather not post my workaround code to solve this bug.
grunt.initConfig({
html2js: {
myapp:
options: {
// custom options, see below
},
main: {
src: ['src/**/*.tpl.html'],
dest: 'tmp/templates.js'
}
}
myotherapp: {
options: {
// custom options, see below
},
main: {
src: ['common/**/*.tpl.html'],
dest: 'tmp/templates_2.js'
}
}
}
})
The version 0.3.7
is not published to the npm registry.
Long or multiple html files takes a lot of time to process, so a delay or halt will be a great help.
Maybe I should ask this directly on the htmlmin github page, but I'm not sure.
I noticed that this configuration:
htmlmin: {
collapseWhitespace: true,
removeComments: true,
collapseBooleanAttributes: false,
removeAttributeQuotes: false,
removeEmptyAttributes: false,
removeRedundantAttributes: false,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: false
}
And this piece of html (bootstrap-ui)
<form class="form-inline">
<div class="form-group">
<button class="btn btn-default btn-sm"><span class="glyphicon glyphicon-pencil"></span></button>
</div>
<div class="form-group">
<button class="btn btn-default btn-sm"><span class="glyphicon glyphicon-repeat" /></button>
</div>
<div class="form-group">
<button class="btn btn-default btn-sm" ><span class="glyphicon glyphicon-remove" /></button>
</div>
</form>
And when I turn off "collapse white space", ie:
collapseWhitespace: false,
So...
Hi,
when I'm using < (less than) operator in an expression e.g.
{{ 4 < 5 }}
then I get verbose output:
Parse Error: < 5 }}
So are angular expressions not fully supported ๐ข ?
Im using grunt-angular-builder to concat and minify AngularJs application. However this plugin requires only one module definition per file.
How could I fix this problem?
I just lost few hours trying to figure out why a bit of ng-route
in angular was not working when compiling from the Jade files.
It seems html2js
transforms empty attributes instead of leaving them "naked".
For instance: div(ui-view)
becomes <div ui-view="ui-view"></div>
instead of <div ui-view></div>
Is there a way to solve the issue?
EDIT: using grunt-contrib-jade
the problem can be solved by adding {doctype: "html"}
to the task options. We need something similar.
This is my devDependencies
in package.json
"devDependencies": {
"bower": "^1.7.9",
"bower-installer": "^1.2.0",
"grunt": "^1.0.0",
"grunt-cli": "^1.2.0",
"grunt-contrib-concat": "^1.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-less": "^1.0.0",
"grunt-contrib-uglify": "^1.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-html2js": "^0.3.5",
"grunt-notify": "^0.4.3",
"less-plugin-clean-css": "^1.0.0",
"recursive-readdir": "^2.0.0"
}
The error I'm getting is ...
npm WARN peerDependencies The peer dependency grunt@~0.4.0 included from grunt-html2js will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm WARN optional dep failed, continuing [email protected]
npm ERR! Windows_NT 6.3.9600
npm ERR! argv "C:\\Program Files (x86)\\nodejs\\\\node.exe" "C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! node v0.12.2
npm ERR! npm v2.7.4
npm ERR! code EPEERINVALID
npm ERR! peerinvalid The package grunt does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants grunt@>=0.4.0
npm ERR! peerinvalid Peer [email protected] wants grunt@~0.4.0
npm ERR! Please include the following file with any support request:
npm ERR! C:\wamp\www\xxxxxx\npm-debug.log
I guess grunt-html2js isn't compatible with V1+ of grunt? Or that this is an oversight.
The content of this template:
<div ui-view=''>
<h1>{{title}}</h1>
<p class='introduction' translate='lican.intro.text'></p>
<form ng-submit='startAnalysis()'>
<button class='btn btn-default' translate='lican.intro.start' type='submit'> </button>
</form>
</div>
is incorrectly minified to:
"<div ui-view><h1>{{title}}</h1><p class=introduction translate></p><form ng-submit=startAnalysis()><button class=\"btn btn-default\" translate type=submit></button></form></div>"
The translate attribute loses its value.
I've been using this plugin, and can't thank you enough for it!
I have an idea for an interesting feature, and I'd like to discuss it before attempting to develop it.
The idea is to add a process
option, that allows for processing of each template as it is loaded. Ideally it would be the same as https://github.com/gruntjs/grunt-contrib-concat#process, or a subset of that functionality.
To sum up, the process
option would either be a Function(html, filePath)
that can alter the HTML. Or, it can be true
, which tells Grunt to process using grunt.template.process
.
My specific use-case is localization, although I'm certain there are additional valuable use-cases.
Within my templates, I want to have literal text. Example: <h2> You have {{ emails.length }} unread messages </h2>
.
However, I also want to translate this to other languages.
So, the process
option would allow me to rewrite this as: <h2> <%= messages.emails.unread %> </h2>
. And now, I can put all messages into messages_en.js
, and load them into my Gruntconfig.js.
Is there anyway when running html2js, to have it not run jshint?
We get the following error:
Loading "jshint.js" tasks...ERROR
>> Error: Cannot find module 'jshint/src/cli/cli'
I've set base option however the compiles result has not been taken this into consideration.
html2js: {
app: {
options: {
base: "app",
htmlmin: {
collapseWhitespace: true,
conservativeCollapse: false,
removeComments: true,
removeEmptyAttributes: true,
caseSensitive: true
}
},
src: ['<%= src.tpl %>'],
dest: '<%= TEMP_ASSETS_DIR %>/<%= templates_file %>.js',
module: '<%= templates_file %>'
}
},
And the result... ../src/app/
angular.module("templates",["../src/app/colors/colors.tpl.html"]),angular.module("../src/app/colors/colors.tpl.html",[]).run(["$templateCache",function($templateCache){$templateCache.put("../src/app/colors/colors.tpl.html",'<div class="btn-group" data-ng-controller="Colors"><button type="button" class="btn btn-default" data-ng-repeat="color in numberOfColors track by $index">Color {{$index}}</button></div>')}]);
html2js does not seem to work within a requirejs environment. Is it possible to add a property which will wrap its output in a requirejs-friendly format?
Example:
define ["angular"], function(angular) {
});
I just updated to Version 0.3.8 and now i am receiving this error message, I am wondering how to solve this issue.
Running "karma:unit" (karma) task
27 03 2017 14:32:52.847:INFO [karma]: Karma v1.5.0 server started at http://0.0.0.0:8085/
27 03 2017 14:32:52.849:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
27 03 2017 14:32:52.853:INFO [launcher]: Starting browser PhantomJS
27 03 2017 14:32:53.319:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket 4O7Q6-2YkABukAhAAAAA with id 49466785
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
SyntaxError: Unexpected EOF
at node_modules/grunt-html2js/test/fixtures/broken_newlines.tpl.html.js:9
Here is my Package.json file:
"devDependencies": {
"grunt": "1.0.1",
"grunt-autoprefixer": "3.0.4",
"grunt-concurrent": "2.3.1",
"grunt-contrib-clean": "1.0.0",
"grunt-contrib-concat": "1.0.1",
"grunt-contrib-connect": "1.0.2",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-cssmin": "2.0.0",
"grunt-contrib-htmlmin": "2.3.0",
"grunt-contrib-imagemin": "1.0.1",
"grunt-contrib-jshint": "1.1.0",
"grunt-contrib-less": "1.4.0",
"grunt-contrib-uglify": "2.2.0",
"grunt-contrib-watch": "1.0.0",
"grunt-debug-task": "0.1.8",
"grunt-filerev": "2.3.1",
"grunt-html2js": "0.3.8",
"grunt-karma": "2.0.0",
"grunt-ng-annotate": "3.0.0",
"grunt-ngdocs": "0.2.10",
"grunt-protractor-runner": "5.0.0",
"grunt-text-replace": "0.4.0",
"grunt-usemin": "3.1.1",
"grunt-wiredep": "3.0.1",
"jasmine-core": "2.5.2",
"jshint-stylish": "2.2.1",
"karma": "1.5.0",
"karma-coverage": "1.1.1",
"karma-html-reporter": "0.2.7",
"karma-jasmine": "1.1.0",
"karma-ng-html2js-preprocessor": "1.0.0",
"karma-phantomjs-launcher": "1.0.4",
"load-grunt-tasks": "3.5.2",
"phantomjs-polyfill": "0.0.2",
"protractor": "5.1.1",
"serve-static": "1.12.1",
"time-grunt": "1.4.0"
}
I would really like an option like useExistingModule
that will in conjunction with singleModule: true
use a angular.module(targetModule).run(...)
instead of angular.module(targetModule, []).run(...)
definition. because now I need to dynamically add the template module as a dependency if i'm in production mode (I only use html2js in production).
I could do a PR if you want.
Instead using a one line:
angular.module('xx.navbar.tmpl', ['xx/navbar-item.html', 'xx/navbar-sub.html', 'xx/navbar-subitem.html', 'bb/navbar.html']);
To prevent warn/error in linters (JSCS, JSHint, etc) break new line for each module:
angular.module('xx.navbar.tmpl', [
'xx/navbar-item.html',
'xx/navbar-sub.html',
'xx/navbar-subitem.html',
'xx/navbar.html'
]);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.