Coder Social home page Coder Social logo

jonkemp / gulp-useref Goto Github PK

View Code? Open in Web Editor NEW
705.0 13.0 93.0 586 KB

Parse build blocks in HTML files to replace references to non-optimized scripts or stylesheets.

License: MIT License

JavaScript 97.84% CSS 0.30% HTML 1.86%
useref gulp-plugin

gulp-useref's People

Contributors

alecrust avatar burgov avatar chaizhenhua avatar discojonathan avatar estliberitas avatar fdiskas avatar gabrielflorit avatar jamesknelson avatar jimmytheneutrino avatar jonkemp avatar my-cereal avatar palmerj avatar rwillmer avatar shgtkshruch avatar shinnn avatar stevemao avatar timdp avatar tkrotoff avatar truongsinh avatar vmarkovtsev avatar vseventer avatar wjordan avatar xmlking 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  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  avatar  avatar  avatar

gulp-useref's Issues

Look up assets in temp directory

I'm trying to migrate a project from grunt to gulp. In the gulp plugins repository there is a recommendation to use gulp-useref instead of gulp-usemin. Is there a similar way to look up asset files in several dirs? E.g. .tmp and app:

<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<!-- endbuild -->

If not, what's the right way to use gulp-useref in a project which uses several languages, e.g. (JS and CoffeeScript)? With the standard configuration it's already late to transform the path in gulpfile.js:

gulp.src('app/*.html')
    .pipe(useref.assets()) // <-- after this line asset files are already concatenated
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore())
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(gulp.dest(conf.dist))

Generate more meaningful error message

Suppose if js/css source files are missing (or search path is not configured properly), I am getting error like following. There is no debug information in it. If I have 10 js/css files, I don't have any clue which file is generating this error. I request you to catch the error and generate more meaningful error like "unable to find file xyz".

stream.js:94                                       
      throw er; // Unhandled stream error in pipe. 
            ^                                      
TypeError: path must be a string                   
  at Object.fs.openSync (fs.js:427:18)             
  at Object.fs.readFileSync (fs.js:284:15)         

How to specify which block to do what tasks

In your example, you have .pipe(gulpif('*.js', uglify())) to do uglify() if the block is js. What if I want to specify which block to do task, how can I do it? I tried .pipe(gulpif('combined.js', uglify())) but it didn't work. Thanks.

Fails when asset is missing--blows up if

When an asset is missing, gulp-useref gives an error message and then exits gulp.

But this:

return gulp.src(['app/index.html', 'app/components/*.html'])
      .pipe(debug()) 
      .pipe(useref.assets())

Produces a big, messy stack trace (see bottom of issue). The same thing happens using gulp-size instead of gulp-debug and might exist with other things in the pipeline before useref.assets

Both problems go away by using:

    .pipe(useref.assets().on("error", gutil.log))

This gives an error message and then continues, despite the missing file.

Stack trace:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
  at TypeError (<anonymous>:null:null)
  at Transform.EventEmitter.emit (events.js:74:15)
  at Transform.onerror (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:522:12)
  at Transform.EventEmitter.emit (events.js:95:17)
  at Transform.<anonymous> (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/index.js:71:42)
  at Array.forEach (native)
  at Transform.<anonymous> (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/index.js:61:35)
  at Array.forEach (native)
  at Transform.<anonymous> (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/index.js:43:36)
  at Array.forEach (native)
  at Transform._transform (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/index.js:40:23)
  at Transform._read (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
  at Transform._write (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12)
  at doWrite (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:238:10)
  at writeOrBuffer (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:228:5)
  at Transform.Writable.write (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:195:11)
  at write (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:587:24)
  at flow (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:596:7)
  at Transform.pipeOnReadable (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:628:5)
  at Transform.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:412:10)
  at emitReadable (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:408:5)
  at readableAddChunk (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:169:9)
  at Transform.Readable.push (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:131:10)
  at Transform.push (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:140:32)
  at Transform._transform (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/index.js:29:8)
  at Transform._read (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:179:10)
  at Transform._write (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:167:12)
  at doWrite (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:229:10)
  at writeOrBuffer (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:219:5)
  at Transform.Writable.write (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp-size/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:186:11)
  at Stream.ondata (stream.js:51:26)
  at Stream.EventEmitter.emit (events.js:95:17)
  at queueData (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:43:21)
  at next (/home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:71:7)
  at /home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:85:7
  at /home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp/node_modules/vinyl-fs/lib/src/bufferFile.js:8:5
  at fs.js:266:14
  at /home/awesome/Apps/NewMULTI/MULTIplex/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/graceful-fs.js:105:5
  at Object.oncomplete (fs.js:107:15)

Has no method 'assets' and Has no method 'restore'

Hey there, I'm trying to roll with something like the first example in the readme file, but I'm receiving errors when trying to run my task.

gulp.task('abc', function() {
    // 5 - Index file
    return gulp.src('app/*.html')
        .pipe(useref.assets())
        .pipe(useref.restore())
        .pipe(gulp.dest('./dist'));
});

See error here: http://pastebin.com/4jW3yMNz

I'm running with 0.2.0 useref and 0.10.22 Node
Thanks

Is it possible to reserve comments in build blocks?

For example, I have this build block:

<!-- build:js scripts/ie.js -->
<!--[if lt IE 9]>
<script src="bower_components/respond/dest/respond.min.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
<![endif]-->
<!-- endbuild -->

Currently, gulp-useref removes the conditional comment and only outputs:

<script src="scripts/ie.js"></script>

But the expected output should be:

<!--[if lt IE 9]>
<script src="scripts/ie.js"></script>
<![endif]-->

Any idea?

build:remove

Is there a build:remove type functionality on the radar? There are some scripts (mock API using angularMock and such) that only belong in a development environment.

Example:

<html>
<head>
    <!-- build:css css/combined.css -->
    <link href="css/one.css" rel="stylesheet">
    <link href="css/two.css" rel="stylesheet">
    <!-- endbuild -->
</head>
<body>
    <!-- build:remove -->
    <script type="text/javascript" src="scripts/somedevelopmentonlyscript.js"></script>
    <script type="text/javascript" src="scripts/mockapi.js"></script>
    <!-- endbuild -->

    <!-- build:js scripts/combined.js -->
    <script type="text/javascript" src="scripts/one.js"></script>
    <script type="text/javascript" src="scripts/two.js"></script>
    <!-- endbuild -->
</body>
</html>

useref choking for unknown reason

I've got useref in my gulp pipeline:

  return gulp.src(['*.html', 'templates/*'], {cwd: 'www', base: 'www'})
    .pipe(useref.assets())
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(gulp.dest('dist'))

Even with an index.html that has no useref directives in it, I get this error now:

/.../node_modules/gulp-useref/index.js:40
        var output = useref(file.contents.toString());
                                          ^
TypeError: Cannot call method 'toString' of null
    at Transform._transform (/.../node_modules/gulp-useref/index.js:40:43)
    at Transform._read (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
    at Transform._write (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12)
    at doWrite (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:238:10)
    at clearBuffer (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:317:5)
    at onwrite (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:275:7)
    at WritableState.onwrite (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:107:5)
    at afterTransform (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:104:5)
    at TransformState.afterTransform (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:79:12)
    at afterWrite (/.../node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:290:3)

not maintaining relative paths

Gulp Task

gulp.task('build-css-usemin', function() {

var assets = useref.assets();

return gulp.src('/views/index.html')
    .pipe(assets)
    .pipe(rev())
    .pipe(assets.restore())
    .pipe(useref())
    .pipe(revReplace())
    .pipe(gulp.dest('test'));

});

HTML

<!-- build:css styles/critical.concat.css -->
<link rel="stylesheet" href="../styles/content.css">
<!-- endbuild -->

Source Directory Structure:

app
-- styles
---- content.css
-- views
---- index.html

Output Directory Structure:

test
-- index.html
-- styles
---- critical.concat.css

while output required is:

views
-- test
---- views/index.html
---- styles
---- critical.concat.css

Cannot use multiple instances

var restoreStream = through.obj();

The restore stream is global in the module, so if you use multiple tasks that use useref the assets() method will put all the files in the same restore stream.

Maybe we could pass a stream into the assets() method, like so

pipe(useref.assets( { restoreStream: myStream } ))

and in the restore function we could pass that in

Rename to revved file names if found

grunt-usemin will rename the references to the files to their revved versions if found on disc. This is a nice feature to combat caching issues, and I'd love to see it in gulp-useref.

useref.assets() does not ignore empty build blocks

I noticed that if you have an empty build block, gulp-useref does not ignore it, but instead generates an empty file. Example:

<!-- build:css styles/vendor.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->

The above markup will generate an empty vendor.css file in gulp-useref.

Cannot find module 'useref'

Seems like this package was unpublished, which means that this no longer works (at least on my end).

Is there a fix for this?

Vendor prefixed files

I have this in the html file.

<!-- build:css styles/vendor.css -->
        <!-- bower:css -->
        <link rel="stylesheet" href="bower_components/mobiscroll/css/mobiscroll.scroller.css" />
        <!-- endbower -->
        <!-- endbuild -->

And I have this in my gulpfile.js

gulp.task('html', ['styles'], function () {
  var lazypipe = require('lazypipe');
  var cssChannel = lazypipe()
    .pipe($.csso)
    .pipe($.replace, 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap','fonts');
  var assets = $.useref.assets({searchPath: '{.tmp,app}'});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', cssChannel()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true})))
    .pipe(gulp.dest('dist'));
});

It's breaking because it tries to look for the file bower_components/mobiscroll/css/scroller.css instead of mobiscroll.scroller.css

How can I fix this? Thanks.

Byte Order Mark should be stripped.

  • lets say i am concatenating a.js and b.js
  • lets say both have byte order marks in beginning ( some bower packages have BOM on them :-( ).
  • gulp-useref concatenates them with byte order mark in between.
  • This is majorly because fs.readFileSync don't strip BOM nodejs/node-v0.x-archive#1918 , and they say developer should strip it if required.
  • so before concatenating BOM should be stripped.

Do not replace file but add output in result section

I use template engine which decide what scripts will be used in production and what in development like this:

<% if @isProduction() : %>
<!-- result: css -->
   ... Anything here will be replaced with compilled css link
<!-- endresult  -->
<!-- result: js -->
   ... Anything here will be replaced with compilled js sript
<!-- endresult  -->
<% else : %>
  <!-- build: css combined.css -->
   ... css links
  <!-- endbuild -->
  <!-- build: js combined.js -->
   ... js scripts
  <!-- endbuild -->
<% end %>

It would be nice if to have ability not to completly replace template file but replace only replace section with apropriate data.

Error after upgrading

Hi, I have a project on v0.4.3 which works fine, but when I update to v1.0.1, gulp-useref breaks when I call useref.restore().
Any advice?

uglify does not create a file

I want to parse ect template file then cat and uglify all the scripts, but useref does not create any js file. I use such configuration:

//gulpfile.js
gulp.task('cat', function () {
  var jsFilter = filter('*.js');

  gulp.src('views/shared/application_scripts.ect')
    .pipe(useref.assets())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore());
});
<!-- views/shared/shared.ect -->
...
<!-- build:js assets/ assets/js/combined.js -->
  <script type="text/javascript" src="/js/vendor/paper.js"></script>
  ...
  <!-- plugins end -->

  <!-- general scripts start -->
  <script type="text/javascript" src="/js/client/dev/app.js"></script>
  ...
  <!-- general scripts end -->

  <!-- client start -->
  <script type="text/javascript" src="/js/client/client.js"></script>
  <!-- client end -->
<!-- endbuild -->
...

Is there a way to add `data-main` to generated block?

is there a way to add data-main to generated block

Before processing:

<!-- build:js scripts/vendor.js -->
<script src="../bower_components/requirejs/require.js" data-main="config"> </script>
<!-- endbuild -->

Expected: After processing

<script src="scripts/vendor.js" data-main="scripts/bootstrap" ></script>

How do I separate the destination of the built .html and the assets?

So the following task places assets and new .html into the dist folder.

gulp.task('default', function () {
    return gulp.src('app/*.html')
        .pipe(useref.assets())
        .pipe(useref.restore())
        .pipe(useref())
        .pipe(gulp.dest('dist'));
});

But what if I have a much more complicated setup, where I want to replace the useref blocks from a php file โ€” say โ€” app/layouts/default.php and replace it as app/layouts/default.min.php while preserving app/layouts/default.php for continuing development purpose, also while keeping the concatenated assets in say public/assets/?

This task here isn't doing the job.

gulp.task('scripts-min', function() {
    var jsFilter = $.filter('**/*.js');

    return gulp.src('app/views/layouts/*.php')
        .pipe($.useref.assets({
            searchPath: 'public'
        }))
        .pipe(jsFilter)
        .pipe($.uglify())
        .pipe(jsFilter.restore())
        .pipe($.useref.restore())
        .pipe($.useref())
        .pipe(gulp.dest('public'))
        .pipe($.size());
});

Are there any options/parameters that I can pass to configure this sort of setup?

Help much appreciated.

just replace block with given script without concatenation possible ?

I am using RequireJS during development time to load scripts and RequireJS Optimizer for concatenation and Minification for production.
concatenated bootstrap.js file is generated by r.js Optimizer in dist/scripts folder.
What I would like to see is, just replace scripts block from source index.html with given script and options attributes ( data-main="scripts/bootstrap") without overwriting any script files, i.e., type:replace something like type: remove option

Source index.html file

<!-- build:replace scripts/bootstrap.js data-main="scripts/bootstrap"  NO_CONCATENATE -->
<script data-main="scripts/config" src="../bower_components/requirejs/require.js"> </script>
<!-- endbuild -->

production ready index.html file after build step:

<script data-main="scripts/bootstrap" src="scripts/bootstrap.js"></script>

brace expansion misused searchPath matching

The current searchPath functionality can't be used for paths of length 1 as they won't be matched correctly using glob.sync().

e.g. try something like the following.

glob = require 'glob'
pattern = "{/usr/local}"
console.log "GLOB", glob.sync pattern
pattern = "{/usr/local, foobar}"
console.log "GLOB", glob.sync pattern

produces ....

GLOB []
GLOB [ '/usr/local' ]

Go figure.

-Drew

Pass parametrs to useref

But I do need to change version of my minified js and css link to prevent caching problems. So it would be nice to have somthing like this:

gulp.task('cat', function () {
  var jsFilter = filter('*.js');
  var cssFilter = filter('*.css');
  var date = Date.now();

  gulp.src('views/shared/application_scripts.ect')
    .pipe(useref.assets())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore())
    .pipe(cssFilter)
    .pipe(minifyCss())
    .pipe(cssFilter.restore())
    .pipe(useref.restore())
    .pipe(useref({
       date: date,
       name: 'minified'
     }))
    .pipe(gulp.dest('./test.html/test'));
});

And in html use #{date} to substitute date in the string

<!-- build: css alternative/path #{name}_#{date}.css -->
...

TypeError: Uncaught, unspecified "error" event.

Hey!

I'm experiencing a weird error with my project and I suspect it's coming from gulp-useref.
My gulpfile used to work without errors, but after I updated, it doesn't work.

Error:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at Transform.EventEmitter.emit (events.js:74:15)
    at Transform.onerror (/Users/***/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:540:12)
    at Transform.EventEmitter.emit (events.js:95:17)
    at Transform.<anonymous> (/Users/***/node_modules/gulp-useref/index.js:80:42)
    at Array.forEach (native)
    at Transform.<anonymous> (/Users/***/node_modules/gulp-useref/index.js:68:35)
    at Array.forEach (native)
    at Transform.<anonymous> (/Users/***/node_modules/gulp-useref/index.js:46:36)
    at Array.forEach (native)

Gulpfile.js:

gulp.task('html', ['html:clean'], function(){
  var jsFilter  = filter('**/*.js')
    , cssFilter = filter('**/*.css')
    , htmlFilter = filter('**/*.html');

  return gulp.src([Config.paths.app.root + '/*.html', '!./app/lib/**'])
    .pipe(useref.assets())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore())
    .pipe(cssFilter)
    .pipe(minifyCss())
    .pipe(cssFilter.restore())
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(htmlFilter)
    .pipe(minifyHtml({ quotes: true, conditionals: true }))
    .pipe(htmlFilter.restore())
    .pipe(gulp.dest(Config.paths.dist.root));
})

Versions:

โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚   โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ”‚   โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚   โ””โ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”‚     โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚     โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚     โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ”‚     โ””โ”€โ”€ [email protected]
โ”‚ โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚ โ”‚   โ””โ”€โ”€ [email protected]
โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚   โ”œโ”€โ”ฌ [email protected]
โ”‚   โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚   โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚   โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚   โ”‚ โ””โ”€โ”€ [email protected]
โ”‚   โ””โ”€โ”€ [email protected]

End Tag (/) removed from <link>

Resubmitting as per Gulp User Suggestion.(gulpjs/gulp#639)

We use HTML 5 based template engine (Thymeleaf), which will use strict mode to validate HTML documents. In short, At run time, they validate whether all HTML tags are closed properly like in XMLs. Consider we have below code inside our HTML

<link rel="stylesheet" href="styles/main.css"/>

Once I run gulp build ( i used generator-gulp-angular), I noticed that, in the dist folder, the above HTML code becomes

<link rel="stylesheet" href="styles/main.css">

without the '/' at the end which will be considered as unclosed tag.

[bug] CSS link tag trailing slash

Let's say I have:

<!-- build:css build/css/app.min.css -->
<link rel="stylesheet" href="/assets/third-party/bootstrap/dist/css/bootstrap.min.css">
<!-- endbuild -->

which outputs:

<link rel="stylesheet" href="build/css/app.min.css"/>

This is invalid HTML because the link tag should not contain a trailing slash. I'm running into this bug trying to run gulp-prefix on the link tags after useref completes, but gulp-prefix bails on the link tags created by gulp-useref on account of this trailing slash. I'm guessing this is an error downstream from gulp-useref itself, but maybe one of the project contributors could point me in the right direction to getting this fixed?

dependency errors on install

npm ERR! notarget No compatible version found: useref@'>=0.2.6-0 <0.3.0-0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["0.0.1","0.1.0","0.2.0"]
npm ERR! notarget
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

npm ERR! System Darwin 13.1.0
npm ERR! command "node" "npm" "install" "--save-dev" "[email protected]"

Feature request: specific url rebase for css files

Let's take for example this:

  <!-- build:css(app) css/compiled/main.min.css -->
  <link href="bower/bootstrap/dist/css/bootstrap.css" rel="stylesheet">
  <link href="bower/font-awesome/css/font-awesome.css" rel="stylesheet">
  <link href="bower/animate.css/animate.css" rel="stylesheet">

  <link href="css/compiled/main.css" rel="stylesheet">
  <link href="css/compiled/page1.css" rel="stylesheet">
  <link href="css/compiled/page2.css" rel="stylesheet">
  <!-- endbuild -->

Now I kept all my compiled css (from sass) into the same folder compiled/ as the result concatenated file css/compiled/main.min.css so that the refs (various url (..)) are still valid.

The problem comes with files that are not there like font awesome that has a relative path looking for ../fonts/fontawesome-webfont.eot for example.

It would be nice to have something like:

  <!-- build:css(app) css/compiled/main.min.css -->
  ...
  <link href="bower/font-awesome/css/font-awesome.css" rel="stylesheet" base="bower/font-awesome/css/">
  ...
<!-- endbuild -->

and have it prefixed to every relative path that's in the file.

How does it sound?

please provide support for gulp-sourcemaps

What are the chances that support for gulp-sourcemaps can be added? I need to have the ability to generate a sourcemap that includes the original files (not the concatenated one).

Maybe I can already do this and I just can't figure it out?

Useref causing problems in gulp html task

Hi,
I have bower_components in the project root directory, I don't have a rogue .bowerrc file in my home directory, this was working at home but when I pulled it onto another machine I ran into some problems. Everything runs until I get to the HTML task.

The gulp task that breaks:

gulp.task('html', ['views', 'styles'], function () {
  var lazypipe = require('lazypipe');
  var cssChannel = lazypipe()
    .pipe($.csso)
    .pipe($.replace, 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap','fonts');
  var assets = $.useref.assets({searchPath: '{.tmp,app}'});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', cssChannel()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe(gulp.dest('.tmp'))
    .pipe(gulp.dest('dist'));
});

The gulp error:

events.js:74
        throw TypeError('Uncaught, unspecified "error" event.');
              ^
TypeError: Uncaught, unspecified "error" event.
    at TypeError (<anonymous>)
    at Transform.emit (events.js:74:15)
    at Transform.onerror (/Applications/MAMP/htdocs/Code/Github/josephdburdick/gulp/macarena/node_modules/gulp/node_modules/vinyl-fs/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_readable.js:588:12)
    at Transform.emit (events.js:95:17)
    at Transform.<anonymous> (/Applications/MAMP/htdocs/Code/Github/josephdburdick/gulp/macarena/node_modules/gulp-useref/index.js:79:42)
    at Array.forEach (native)
    at Transform.<anonymous> (/Applications/MAMP/htdocs/Code/Github/josephdburdick/gulp/macarena/node_modules/gulp-useref/index.js:67:35)
    at Array.forEach (native)
    at Transform.<anonymous> (/Applications/MAMP/htdocs/Code/Github/josephdburdick/gulp/macarena/node_modules/gulp-useref/index.js:45:36)
    at Array.forEach (native)

Serious performance issues. Stucked :(

Hi,

I'm experiencing serious performance issues while using gulp-useref. App is pretty simple 20 html files that contains references to a couple images (10โ€“20 total) and few js files are attached (same set of files in every html file).

Am I doing something wrong?

task:

gulp.task('html', ['styles'], function () {

  var shouldMinifyJs = function(file){
    return !!(env === 'production' && $.match(file, '*.js'));
  };

  var shouldMinifyCss = function(file){
    return !!(env === 'production' && $.match(file, '*.css'));
  };

  var shouldMinifyInline = function(file){
    return !!(env === 'production' && $.match(file, '*.html'));
  };

  var assets = $.useref.assets({searchPath: '{.tmp,src}'});
  return gulp.src('.tmp/**/*.html')
    .pipe(assets)
    // Concatenate And Minify JavaScript
    .pipe($.if(shouldMinifyJs, $.uglify()))
    // Concatenate And Minify Styles
    // In case you are still using useref build blocks
    .pipe($.if(shouldMinifyCss, $.csso()))
    // Set Revision
    .pipe($.if(env == 'production', $.rev()))
    .pipe(assets.restore())
    .pipe($.useref())
    // Update revision
    .pipe($.if(env == 'production', $.revReplace()))
    // Minify inline JS
    .pipe($.if(shouldMinifyInline, $.minifyInline()))
    // Minify Any HTML
    .pipe($.if(shouldMinifyInline, $.minifyHtml()))
    // Put vars into html
    .pipe($.preprocess({context: { env: env}}))
    // Output Files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});

typical html file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

    <!-- build:css styles/main.css -->

    <link rel="stylesheet" href="/startup/flat-ui/bootstrap/css/bootstrap.css">
    <link rel="stylesheet" href="/startup/flat-ui/css/flat-ui.css">
    <link rel="stylesheet" href="/startup/common-files/css/icon-font.css">
    <link rel="stylesheet" href="/startup/common-files/css/animations.css">
    <link rel="stylesheet" href="/bower_components/animate.css/animate.css">
    <link rel="stylesheet" href="/bower_components/fontawesome/css/font-awesome.css">
    <link rel="stylesheet" href="/styles/cookiecuttr.css">
    <link rel="stylesheet" href="/styles/main.css">
    <!-- endbuild -->

    <!-- build:js scripts/vendor/modernizr.js -->
    <script src="/bower_components/modernizr/modernizr.js"></script>
    <!-- endbuild -->
</head>
<body>

    ! page content goes here !

    <!-- build:js scripts/vendor.js -->
    <!-- bower:js -->
    <script src="/bower_components/jquery/dist/jquery.js"></script>
    <script src="/bower_components/jquery.cookie/jquery.cookie.js"></script>

    <script src="/startup/flat-ui/js/bootstrap.min.js"></script>
    <script src="/startup/common-files/js/jquery.scrollTo-1.4.3.1-min.js"></script>
    <script src="/startup/common-files/js/page-transitions.js"></script>
    <script src="/startup/common-files/js/easing.min.js"></script>
    <script src="/startup/common-files/js/jquery.svg.js"></script>
    <script src="/startup/common-files/js/jquery.svganim.js"></script>
    <script src="/startup/common-files/js/jquery.parallax.min.js"></script>
    <script src="/startup/common-files/js/jquery.sharrre.min.js"></script>
    <script src="/startup/common-files/js/startup-kit.js"></script>

    <script src="/scripts/jquery.cookiecuttr.js"></script>
    <!-- endbower -->
    <!-- endbuild -->

</body>
</html>

gulp-useref 0.2.1 npm package missing index.js file

I tried to install gulp-useref 0.2.1 from npm today using npm install --save-dev gulp-useref and the folder in node_modules did not have an index.js file, which I understand to be the main entry point for this package from reading the package.json. Tried installing a few times, had same experience every time. just wanted to report

using gulp.watch with gulp-useref causes error on file change

I have created a simple testing environment:

app
|
+- index.html
+- /js
|  +- one.js
|  +- two.js
+- /dist

My gulpfile:

var gulp = require('gulp'),
  useref = require('gulp-useref');

gulp.task('default', function () {
  return gulp.src('index.html')
    .pipe(useref.assets())
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(gulp.dest('dist'));
});

gulp.task('watch', function () {
  gulp.watch('js/**/*.js', ['default']);
});

On start assets are compiled fine, but on changes in .js files I get an error:

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: write after end
    at writeAfterEnd (/Users/vasa/WebstormProjects/useref-test/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:136:12)
    at Transform.Writable.write (/Users/vasa/WebstormProjects/useref-test/node_modules/gulp-useref/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:184:5)
    at Stream.ondata (stream.js:51:26)
    at Stream.EventEmitter.emit (events.js:95:17)
    at queueData (/Users/vasa/WebstormProjects/useref-test/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:43:21)
    at next (/Users/vasa/WebstormProjects/useref-test/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:71:7)
    at /Users/vasa/WebstormProjects/useref-test/node_modules/gulp/node_modules/vinyl-fs/node_modules/map-stream/index.js:85:7
    at /Users/vasa/WebstormProjects/useref-test/node_modules/gulp/node_modules/vinyl-fs/lib/src/bufferFile.js:8:5
    at fs.js:266:14
    at /Users/vasa/WebstormProjects/useref-test/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/graceful-fs.js:105:5

I tried to user gulp-plumber, and there is no error, but resulting assets are not updating.

Relative Path error

It can not find file in relative path.

<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="../bower_components/underscore/underscore.js"></script>
<!-- endbower -->
<!-- Local Files-->
<script src="components/underscore/underscore-factory.js"></script>
<!-- endbuild -->

How do I uglify multiple block of files?

Hi,

I've tried with:

<!-- build:js assets/app1.min.js -->
... (list of scripts)
<!-- endbuild -->

<!-- build:js assets/app2.min.js -->
... (another list of scripts)
<!-- endbuild -->

The html output gives the correct replacement for the app1.min.js and app2.min.js
But the uglify output only contains the app1.min.js which is the minified result of ALL the scripts (all the scripts listed in app1 block + app2 block).

Could you please provide an example of how to achieve this? My code was:

gulp.src('app/index-mini2.html')
    .pipe(useref.assets())
    .pipe(gulpif('*.js', uglify()))
    .pipe(gulpif('*.css', minifycss()))
    .pipe(useref.restore())
    .pipe(useref())
    .pipe(gulp.dest('./app'))

Feature request: emit every file before concat.

I feel like we have no control over what happens internally. It would be nice to process the files involved before the concat.

This is just a really basic code here, just a test case to explain what I mean.
The targetsByFile doesn't really work, and scopes are messed up, but you'll get what I mean.

gulp.task('test', function () {
  var resultHTML
  var buildBlocks
  var targetsByFile = {}

  return gulp.src('app/index.html')
     // parse html and replace blocks
    .pipe(through.obj(function (file, enc, done) {
      var stream = this
      var parsed = useref(file.contents.toString())


      file.contents = new Buffer(parsed[0])
      stream.push(file)

      buildBlocks = parsed[1]

      Object.keys(buildBlocks).forEach(function (blockType) {
        Object.keys(buildBlocks[blockType]).forEach(function (blockTarget) {
          var target = buildBlocks[blockType][blockTarget]
          target.files = []
          target.path = process.cwd() + '/' + target.searchPaths + '/' + blockTarget

          target.assets.forEach(function (filePath) {
            var absolutePath = process.cwd() + '/' + target.searchPaths + '/' + filePath

            targetsByFile[absolutePath] = target

            stream.push(new gutil.File({
              base: process.cwd() + '/' + target.searchPaths,
              path: absolutePath,
              contents: fs.readFileSync(absolutePath)
            }))
          })
        })
      })

      done()
    }))
    // do something with css files
    .pipe(plugins.if('*.css', through.obj(function (file, enc, done) {
      console.log(file.path)
      this.push(file)
      done()
    })))
    // concat by target
    .pipe(through.obj(function (file, enc, done) {
      var target = targetsByFile[file.path]

      if (!target) {
        return this.push(file)
      }

      target.files.push(file.contents.toString())

      if (target.files.length === target.assets.length) {
        this.push(new gutil.File({
          path: target.path,
          contents: new Buffer(target.files.join(gutil.linefeed))
        }))
      }

      done()
    }))
    // only concat targets and index.html reach this point
    .pipe(plugins.if('*.js', plugins.uglify()))
    .pipe(plugins.if('*.css', plugins.minifyCss( { keepSpecialComments: 0, keepBreaks: true })))
    // just for logging
    .pipe(through.obj(function (file, enc, done) {
      // console.log(file.path)
      this.push(file)
      done()
    }))
    .pipe(gulp.dest('test'))
})

New API should be

gulp.task('html', function () {
  var assets = plugins.useref.assets()

  return gulp.src('app/index.html')
    .pipe(assets)
    // emit all the files
    .pipe(plugins.if('*.css', fixCSSPaths()))
    .pipe(plugins.if('main.css', doSomething()))
    .pipe(assets.concat())
    // emit only concatenated files and index.html
    .pipe(plugins.if('*.js', plugins.uglify()))
    .pipe(plugins.if('*.css', plugins.minifyCss( { keepSpecialComments: 0, keepBreaks: true })))
    .pipe(assets.replaceHTML())
    .pipe(gulp.dest('dist'))
})

how to apply some minification to css and js separately

Hi,
I'm trying to figure out how to use the results from useref (the list of files for css and js) to apply minification and concatenation to them. You mention this should be done by seperate plugins. I understand the rationale behind this. Could you split the streams based on the css or js tags? Or apply some mapping function?

Process assets before concat

Is there a way to use the useref parsing and get a stream of assets?

I'd like to hook in preprocessing on some files (ngmin + uglify the files I wrote, leave the libraries untouched, with gulp-if).

Ideally this could be something like useref.files(), which contains a stream of the individual files that make up useref.assets(). But maybe I'm missing something, perhaps this is already possible.

Any advice appreciated!

Possible to generate random name?

Is it possible to generate random name? maybe make it random if no name is assigned:

<!-- build:css -->
    <link href="css/one.css" rel="stylesheet">
    <link href="css/two.css" rel="stylesheet">
<!-- endbuild -->

or receive a defined name from the build task?

build:css with params not respecting media attributes

Looks like the media attribute on link elements is not being respected.
I have the following input:

<!-- build:css css/styles.css media="screen and (min-width: 40em)" -->
<link rel="stylesheet" href="css/styles.css" media="screen and (min-width: 40em)" />
<!-- endbuild -->

translating to this (after building):

<link rel="stylesheet" href="css/styles.css" media="screen and (min-width>

Not really sure if this is an issue in gulp-useref or in useref itself.
Any ideas, feedback, ... would be welcome!

Can't htmlmin after useref

useref works great, htmlmin works great too, but one after another they cause an error:

  return gulp.src('.tmp/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.htmlmin())
    .pipe(gulp.dest("dist"))
    .pipe($.size());

Error:

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: no writecb in Transform class
  at afterTransform (/app/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:95:33)
  at TransformState.afterTransform (/app/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:79:12)
  at /app/node_modules/gulp-uglify/index.js:70:12
  at minify (/app/node_modules/gulp-uglify/index.js:18:3)
  at DestroyableTransform.uglify [as _transform] (/app/node_modules/gulp-uglify/index.js:68:3)
  at DestroyableTransform.Transform._read (/app/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
  at DestroyableTransform.Transform._write (/app/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12)

Concatenation produces JS error

We have been struggling with getting JS concatenation to work properly. We've encountered it with two different libs so far (angular.js + spin.js), both in minified and unminified versions. The browser console throws the following error:
Uncaught SyntaxError: Invalid left-hand side in assignment and upon inspection, it does seem like the concatenation adds a mystical < somewhere in the file. Tested with newest version of gulp-useref (0.5.0). gulp-usemin does NOT produce the same errors.

Complete example?

It would be nice to see a complete example of using useref and bundle together.

Processing unminified files only

Using your example code, I try to minify only unminified files (excluding vendor files ending with *.min.js or *.min.css) :

gulp.task('html', function () {
    var assets = useref.assets();

    return gulp.src('app/*.html')
        .pipe(assets)
        .pipe(gulpif(['js/**/*.js', '!*.min.js', '!/**/*.min.js'], uglify()))
        .pipe(gulpif(['css/**/*.css', '!*.min.css', '!/**/*.min.css'], minifyCss()))
        .pipe(assets.restore())
        .pipe(useref())
        .pipe(gulp.dest('dist'));
});

But it doesn't work: All the files are concatenated but not minified. Maybe it isn't exactly an useref issue but has only to do with gulpif returning always false for ["js//.js", "!.min.js", "!//*.min.js"].

How can I achieve this using gulp-useref?

How to use this in django template?

Like this:

<!-- build:css static/dist/sre.min.css -->
<link rel="stylesheet" type=text/css href="{{url_for('static',filename='css/bootstrap.css')}}">
<link rel="stylesheet" type=text/css href="{{url_for('static',filename='css/bootstrap-theme.css')}}">
<link rel="stylesheet" type=text/css href="{{url_for('static',filename='css/select2.css')}}">
<link rel="stylesheet" type=text/css href="{{url_for('static',filename='css/ng-grid.css')}}">

<!-- endbuild -->

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.