Skip to content

Commit

Permalink
Use NPM for obtaining client side dependencies
Browse files Browse the repository at this point in the history
The JavaScript client depends on several libraries, which are currently
tracked in our repository. This makes keeping up with updates unnecessarily
complicated and pollutes the repository.

In the past we faced the same problem with PHP dependencies and we solved it
using Composer. For JavaScript, Bower and NPM are two most common package
managers. Initially, Bower was used for its use of flat dependency tree
but in the end NPM prevailed because it is much more common in distribution
repositories.

This patch modifies the build script to install the dependencies and moves
jQuery dependency to the new system. Other dependencies have yet to come.

As with Composer, nothing changes for normal user; developers will be forced
to update the dependencies on checkout.
  • Loading branch information
jtojnar committed Jun 9, 2017
1 parent d47f721 commit a39f2c3
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 8 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ DEVELOPMENT

Selfoss uses [composer](https://getcomposer.org/) for installing external libraries. When you clone the repository you have to issue `composer install` to retrieve the external sources.

For the client side, you will also need JavaScript dependencies installed by calling `npm install` in the `public` directory.

CREDITS
-------

Expand Down
37 changes: 34 additions & 3 deletions gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,35 @@ function isNotUnimportant(dest) {
}

module.exports = function(grunt) {
const requiredAssets = (function() {
const assets = [];

const index = grunt.file.read('index.php');

index.match(/\$js = \[\n([^\]]*)\];\n/)[1].replace(/'([^']+)'/g, function(_, file) {
assets.push(file);
});

index.match(/\$css = \[\n([^\]]*)\];\n/)[1].replace(/'([^']+)'/g, function(_, file) {
assets.push(file);
});

return assets;
})();

grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),

/* Install client-side dependencies */
auto_install: {
subdir: {
options: {
cwd: 'public',
npm: '--production'
}
}
},

/* version text replace */
replace: {
version: {
Expand Down Expand Up @@ -88,9 +113,14 @@ module.exports = function(grunt) {
{ expand: true, cwd: 'helpers/', src: ['**'], dest: '/helpers'},
{ expand: true, cwd: 'vendor/', src: ['**'], dest: '/vendor', filter: isNotUnimportant},

// public = don't zip all.js and all.css
// do not pack bundled assets and assets not listed in index.php
{ expand: true, cwd: 'public/', src: ['**'], dest: '/public', filter: function(file) {
return file.indexOf('all.js') === -1 && file.indexOf('all.css') === -1;
const bundle = file === 'public/all.js' || file === 'public/all.css';
const packageDesc = file === 'public/package.json';
const thirdPartyRubbish = file.startsWith('public/node_modules/') && requiredAssets.indexOf(file) === -1;
const allowed = !bundle && !packageDesc && !thirdPartyRubbish;

return allowed;
}},

// copy data: only directory structure and .htaccess for deny
Expand All @@ -115,6 +145,7 @@ module.exports = function(grunt) {
}
});

grunt.loadNpmTasks('grunt-auto-install');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-composer');
Expand All @@ -130,7 +161,7 @@ module.exports = function(grunt) {
}
});

grunt.registerTask('default', ['composer:install:no-dev:optimize-autoloader:prefer-dist', 'versionupdater', 'compress']);
grunt.registerTask('default', ['auto_install', 'composer:install:no-dev:optimize-autoloader:prefer-dist', 'versionupdater', 'compress']);
grunt.registerTask('version', ['versionupdater']);
grunt.registerTask('zip', ['compress']);
};
5 changes: 5 additions & 0 deletions helpers/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ public static function maxmtime(array $filePaths) {
$maxmtime = 0;
foreach ($filePaths as $filePath) {
$fullPath = \F3::get('BASEDIR') . '/' . $filePath;

if (!file_exists($fullPath)) {
throw new \Exception("Missing file “${filePath}”. Did you install the dependencies using npm?");
}

$maxmtime = max($maxmtime, filemtime($fullPath));
}

Expand Down
2 changes: 1 addition & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

// define js files
$js = [
'public/js/jquery-2.1.1.min.js',
'public/node_modules/jquery/dist/jquery.js',
'public/js/jquery.mCustomScrollbar.min.js',
'public/js/jquery.mousewheel.min.js',
'public/js/lazy-image-loader.js',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"devDependencies": {
"grunt": "~0.4.5",
"grunt-auto-install": "^0.3.1",
"grunt-composer": "^0.4.5",
"grunt-contrib-compress": "^0.10.0",
"grunt-text-replace": "~0.3"
Expand Down
4 changes: 0 additions & 4 deletions public/js/jquery-2.1.1.min.js

This file was deleted.

5 changes: 5 additions & 0 deletions public/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"jquery": "^2.2.4"
}
}

0 comments on commit a39f2c3

Please sign in to comment.