Ionic / bower / cordova - ignore files for build

2019-03-15 06:26发布

问题:

My project structure is the following:

MyApp
  - hooks
  - platforms
     - android
     - ios
  - www
    - js / css / templates..
    - lib (including all bower components)

Right now, the www/lib directory is taking up 21,8 Mb. (I have a large set of bower components added to my project.)

When building each project, the entire www folder is copied to the platform/android (for instance) folder for build, including of course www/lib.

This leads to a very big build, as lots of files included into bower components are useless for production.

Manually managing all bower dependencies is clearly not an option. So how do you guys manage to clean your project platform directory for build?

I was thinking about creating a hook for that but before writing lines of code in a language that i do not know (nodeJS), I was hoping for your return and advises.

回答1:

According to Cordova workflow you can add a hook script that removes unnecessary files. A detailed example of a cleanup script can be found here: https://blog.nraboy.com/2015/01/hooks-apache-cordova-mobile-applications/

But to give a quick step by step summary:

Add to the after_prepare hook folder (/hooks/after_prepare) a script (01_junk_cleanup.js - 01 to be run first, the rest whatever you want) and in the file specify the files and folders you want to delete. For example, here is how you can delete a test folder and relevant files just change to you lib directory and to the files there. Note that this example is a bit different from the example in the link i gave earlier so you might want to take a look there as well.

01_junk_cleanup.js:

#!/usr/bin/env node

var fs = require('fs');
var path = require('path');

var foldersToProcess = [
    "js",
    "css"

];

var foldersToDelete = [
    "test"
];

var filesToDelete = [
    "karmaOnBrowser.conf.js",
    "karmaOnEmulators.conf.js",
    "SpecRunner.html"
];

var iosPlatformsDir = "platforms/ios/www/";
var androidPlatformsDir = "platforms/android/assets/www/";

filesToDelete.forEach(function(file) {
    var filePathIOS = iosPlatformsDir + file;
    var filePathAndroid = androidPlatformsDir + file;
    if(fs.existsSync(filePathIOS)){
        fs.unlinkSync(filePathIOS);
    };
    if(fs.existsSync(filePathAndroid)){
        fs.unlinkSync(filePathAndroid);
    };
});

foldersToProcess.forEach(function(folder) {
    processFiles(iosPlatformsDir + folder);
    processFiles(androidPlatformsDir + folder);
});

foldersToDelete.forEach(function(folder) {
    deleteFolderRecursive(iosPlatformsDir + folder);
    deleteFolderRecursive(androidPlatformsDir + folder);
});

function deleteFolderRecursive(path){
    if( fs.existsSync(path) ) {
         fs.readdirSync(path).forEach(function(file,index){
             var curPath = path + "/" + file;
             if(fs.lstatSync(curPath).isDirectory()) { // recurse
                deleteFolderRecursive(curPath);
             } else { // delete file
                fs.unlinkSync(curPath);
             }
         });
         fs.rmdirSync(path);
    }
}

function processFiles(dir) {
    fs.readdir(dir, function(err, list) {
        if(err) {
            console.log('processFiles err: ' + err);
            return;
        }
        list.forEach(function(file) {
            file = dir + '/' + file;
            fs.stat(file, function(err, stat) {
                if(!stat.isDirectory()) {
                    switch(path.basename(file)) {
                        case ".DS_Store":
                            fs.unlink(file, function(error) {
                                console.log("Removed file " + file);
                            });
                            break;
                        case "Thumbs.db":
                            fs.unlink(file, function(error) {
                                console.log("Removed file " + file);
                            });
                            break;
                        default:
                            console.log("Skipping file " + file);
                            break;
                    }
                }
            });
        });
    });
}

Aside to above, A bit more obvious but I feel worth mentioning anyhow, After having the www/lib bloat as well I always try to keep the folder lean and add only libraries required for deployment, the other dev. dependencies such as jasmine I either hold in the 'node_modules' folder or 'bower_components' as I only install today through them.

Hope this helps, Good luck



回答2:

I think the best approach would be to do this:

  1. Move the bower_components folder and your index.html file to the project root, outside the /www folder
  2. Install gulp and gulp-usemin
  3. Wrap all of the .js files and .css files from bower components in usemin <build:js> and <build:css> sections
  4. Configure a task in your gulpfile to concatenate all those files into a lib.js and a lib.css file. Make sure that those two files as well as the rewritten index.html are output to the /www folder
  5. Execute the gulp task before your next build, and each time you add a new bower component.

This will keep your /www folder tidy and only containing the files you need in your cordova build.



回答3:

With Bower you need to use npm preen to remove unnecessary files

See my example using Gulp with Ionic Framework: https://github.com/jdnichollsc/Ionic-Starter-Template

Basically you can set your bower.json file to indicate the path which files you need, for example:

"preen": {
    //... More libraries
    "ionic-datepicker": [
        "dist/*.js" //You only need these files
        //Other files and folders will be deleted to reduce the size of your app
    ],
    "ion-floating-menu": [
        "dist/*" //Keep all the files (.html, .css, .js, etc) of the directory.
    ]
}

Regards, Nicholls



回答4:

This is an improvement over this answer. I've applied it to my own project.

  1. Move the bower_components folder to the project root, outside the www folder.
  2. Rename index.html to _index.html. We will later make sure that Gulp automatically generates index.html.
  3. Install gulp and gulp-useref.
  4. Edit your _index.html so that it looks something like this:

    <!-- build:js dist/js/vendor.js -->

    <script src="../bower_components/ionic/release/js/ionic.bundle.min.js"></script>

    <script src="../bower_components/ngstorage/ngStorage.min.js"></script>

    <script src="../bower_components/ngCordova/dist/ng-cordova.min.js"></script>

    <!-- endbuild -->

  5. Configure your gulp watch task to build new index.html file in the www folder with the concatenated files.

var entrypoint = './www/_index.html';

gulp.task('watch', function() {
  gulp.watch(entrypoint, ['concat-js-and-css']);
});

gulp.task('concat-js-and-css', function () {
    return gulp.src(entrypoint)
        .pipe(useref()) 
        .pipe(rename(function (path) {
          // rename _index.html to index.html
          if (path.basename == '_index' && path.extname == '.html') {
            path.basename = "index";
          }
        }))
        .pipe(gulp.dest('./www'))
});

gulp.task('build', ['concat-js-and-css']);

When that task runs, your index.html file will contain just this:

<script src="dist/js/vendor.js"></script>
  1. Edit your ionic.project file so that it looks like the following. This will make sure that gulp watch is run before ionic serve.
{
  "watchPatterns": [
    "www/_index.html",
  ],
  "gulpStartupTasks": [
    "watch"
  ]
}