Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'ng build' with all scripts in subfolder

It is now possible, to get not flat structure of project with ng build, so instead of this:

index.html  
main.bundle.js  
styles.bundle.js  
...

I want scripts to be in subfolder

index.html  
scripts/main.bundle.js  
scripts/styles.bundle.js  
...

I found a topic about this: 'ng build' move scripts to subfolder but hire the solutions is to eject project from cli into webpack but with Angular 7 this is not longer available and ng eject is now disabled:

The 'eject' command has been disabled and will be removed completely in 8.0. The new configuration format provides increased flexibility to modify the configuration of your workspace without ejecting.

There are several projects that can be used in conjuction with the new configuration format that provide the benefits of ejecting without the maintenance overhead. One such project is ngx-build-plus found here: https://github.com/manfredsteyer/ngx-build-plus

Angular provide very poor documentation of angular.json file hire https://github.com/angular/angular-cli/wiki/angular-workspace so it's difficult to use this config file in real project problems.

like image 634
kris_IV Avatar asked Feb 20 '19 19:02

kris_IV


2 Answers

You cannot do that by using the ng build command alone, you can do it by using the following the commands one after the other.

ng build --output-path="dist/scripts" --deployUrl="scripts/"

and

move "dist\scripts\index.html" "dist"

The last command works considering that you are using windows (is just a copy/paste, the magic is done by the --deployUrl command).

As stated by @Nick in comments, this options can also be added on your angular.json file:

...
projects: {
  angular: {
     architect: {
        build: {
          options: {
             outputPath: "dist/scripts",
             deployUrl: "scripts/"
          }
        }
     } 
  }
}

Update 09/09/21: Angular updated their documentation from --deployUrl to --deploy-url, they work the same

like image 172
luiscla27 Avatar answered Oct 09 '22 02:10

luiscla27


create new file called 'move_assets.js' in the root of the application with the following content.

process.argv.forEach(a => {
  if (a.startsWith('--basepath')){
    basepath = a.split('=')[1];
  }
});
var fs = require('fs');
const { interval } = require('rxjs');

var fileCount = null;

if(!basepath){
  console.error('No basepath provided');
}

console.info('Cleaning up file system... Please wait.');
setTimeout(() => {
  console.info('Deleteing old files...');
  fs.readdir(basepath, (err, files) => {
    if(err) {throw err}
    if (files){
      fileCount = files.length;
      files.forEach(item => {
        if(item !== 'scripts'){
          if(fs.existsSync(basepath + item) && fs.lstatSync(basepath + item).isDirectory()){
            fs.rmdir(basepath + item, { recursive: true }, (err) => { if (err) { throw err; } else {fileCount--;}});
          } else {
            fs.unlink(basepath + item, function (err) { if (err) {throw err} else {fileCount--;} });
          }
        }else {
          fileCount--;
        }
      });
    } else {
      fileCount = 0;
    }
  });
}, 1000); //wait for 1 second for file system to breath :)

var timer = setInterval(() => {

  if (fileCount !== null && fileCount < 1) {

    console.info('Moving files.');

    let i = 0;

    const filesToMove = ['assets', 'index.html', 'favicon.ico']
      filesToMove.forEach(f => {
        if(fs.existsSync(basepath + 'scripts/' + f) && (fs.lstatSync(basepath + 'scripts/' + f).isFile() || fs.lstatSync(basepath + 'scripts/' + f).isDirectory())){
          fs.rename(basepath + 'scripts/' + f, basepath + f,function (err) {
            if (err) {throw err}
            else {
              i++;
              console.info(`Successfully moved ${basepath}scripts/${f} --> ${basepath}${f}`);
              if(i == filesToMove.length){
                console.info('Complete!');
              }
            }
          });
        } else {
          console.error(`Cannot move ${basepath}scripts/${f} - item not found`);
        }
    });

    clearInterval(timer);

  }

},500);

in package.json file add line in scripts section

        "buildWithSubfolder": "ng build --base-href / --deployUrl scripts/ --output-path localfolder/scripts/ && node move_assets.js --basepath=/localfolder/"

this will compile an application and dump all the files in the /scripts folder then move index.html, assets, favicon files to the parent folder.

like image 45
Clint Avatar answered Oct 09 '22 01:10

Clint