parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.49k stars 2.27k forks source link

Flag to delete output folder before building #3591

Open mkg20001 opened 5 years ago

mkg20001 commented 5 years ago

🙋 Feature request

A flag/option to delete the output folder before building.

It's common place to do that in order to avoid mixing dev asssets and production assets.

🤔 Expected Behavior

Simply remove the output destination recursively before building via a flag Should be enabled by default.

😯 Current Behavior

It has to be scripted manually.

💁 Possible Solution

Per-target flag/option deleteBeforeBuild which is enabled by default in production build mode. Simply removes the output folder.

🔦 Context

Most people add rm -rf dist; before the parcel command

That's bad for windows users since rm doesn't work that way there

Having it in parcel would make things a lot easier and save the hassle of manually adding the recursive rm command

💻 Examples

$ npx parcel build index.html -o dist --delete-before-build
{
  "target": {
    "browser": {
      "main": "index.html",
      "deleteBeforeBuild": true
    }
  }
}
fagnervalente commented 5 years ago

Hi @mkg20001 After read a bunch of articles about responsibilities of this kind of tools, I advise you to use Gulp + Parcel. Parcel is a bundles as a webpack do, so what you are waiting for is a task better executed by a task manager as a Gulp. In this case, Parcel will run as one of your task list. It is very easy to config and be happy. I wish helped you. Best regards.

Userfull links

mischnic commented 5 years ago

I would say using gulp is overkill here, running rm -rf build && parcel build ... works just fine.

But I still think that this should be somehow integrated into Parcel.

kirillrogovoy commented 5 years ago

I'm sorry if it comes around as a stupid question, but is there really a reason to not remove the output directory before building?

What would be the use case for that?

I feel like removing that directory beforehand is what you would want by default 99% of the time, so just making it the default behavior with no flags involved might make sense, and that other 1% of cases would be handled with manual scripting.

mkg20001 commented 5 years ago

@kirillrogovoy While I tend to agree with that, it's still something someone might want to disable. Although we could also add it and then wait for somebody to request that (disabling auto-deletion) as a feature

kirillrogovoy commented 5 years ago

I'm sure there'll be cases where auto-deletion is undesirable, but I'd be curious to study them.

Ultimately, just as for manual deletion, preservation might be done via scripting around Parcel for that 1 case out of 100. :)

I'm going to see what it'd look like codewise to add auto-deletion.

mkg20001 commented 5 years ago

I'm going to see what it'd look like codewise to add auto-deletion.

Just adding https://npm.im/rimraf propably Although I think it should only auto-delete if the output location is a folder, otherwise in case of files it'll overwrite them

One problematic case would be symlinks, in that case I think it should check if it's a symlink via lstat and instead rimraf all the files in the folder and not the folder (link)

kirillrogovoy commented 5 years ago

So I guess it would look like this — https://github.com/parcel-bundler/parcel/pull/3616.

ianstormtaylor commented 5 years ago

FWIW, if your build step involves multiple different tools, and all of them decide to clear the output directory before building, it makes it extra annoying to get them working together. A good reason for making it a flag.

The term "clean" is often used for this purpose, so it could be --clean.

kirillrogovoy commented 5 years ago

@ianstormtaylor I kind of see what you mean, but I can't come up with an example...

I mean:

  1. The steps in your building process are likely to be sequential; and
  2. You wouldn't want to use the same dir as both the source and the target for building (in other words, changing/creating the files in place). But even then, you should probably engage in some sort of concurrent building to have problems with it.

But I assume I might be missing something obvious here too.

ianstormtaylor commented 5 years ago

@kirillrogovoy the use cases that become annoying are ones where (a) you have to use two different tools (bundlers, transpilers, etc.) and (b) you need them to both use the same directory for their output. There are probably many combinations of edge cases that end up having both constraints.

That said, the flag could either be --clean, or --no-clean if the default was cleaning.

But something to consider too is that there might be big performance gains to be had using caching and not cleaning by default (unless cleaning got a lot smarter than rm -rf). So that might be reason enough to make cleaning opt in. (For example, potentially for copying assets.)

kirillrogovoy commented 5 years ago

My preference would be to have the dist cleaned by default, but I'd go with either.

Waiting for the feedback from the core team.

devongovett commented 5 years ago

Also unlike Parcel 1, Parcel 2 can output files wherever you want (not necessarily into a dist directory). For example, you could have this in your package.json:

{
  "name": "my-package",
  "source": "src/index.js",
  "main": "index.js"
}

In that example, the dist directory is actually the main package dir with all your source code too. You wouldn't want to delete that.

damianobarbati commented 5 years ago

Does parcel@1 plugins still work on parcel@2? I was using parcel-plugin-nuke-dist for this, but it does not work anymore on parcel@2.

mischnic commented 5 years ago

Does parcel@1 plugins still work on parcel@2?

No, the plugin system was completely changed.

ermarkar commented 4 years ago

this is going to be implemented? I guess this is basic functionality, lib should provide, --clean-before-build or --clean flag can be implemented

sergey-shpak commented 4 years ago

at the moment I'm using npm scripts:

"preparcel": "rm -rf dist/",
"parcel": "parcel $RUN src/index.js --no-autoinstall",
"build": "RUN=build npm run parcel -- --no-cache",
"watch": "RUN=watch npm run parcel",
"serve": "RUN=serve npm run parcel",

but it would be nice to clean dist with plugin, etc, also started similar discussion

avalanche1 commented 3 years ago

I would add the same option for parcel serve as well.

elijahmontenegro commented 3 years ago

I have to use the following as a workaround. I really like the idea of a --clean flag but it looks like nobody has implemented such a thing yet. This only works on windows.

del dist /Q && parcel serve ./public/index.html --dist-dir dist

this breaks however if there is not a dist folder existing

teocci commented 2 years ago

The best way to handle this is having control of the code. npm already provides the tools needed for this job. In the package.json, when running commands with &&, the first command will run, and if it does finish without any error, the second command will also be executed. Running &, however, will run each command in the background independently, regardless of what happens to the other command. In other words:

For example:

project/
|dist/
    |...
|src/
    |assets/
        |text.txt
        |memos.txt
        |info.ini
    |css/
        |style.css
    |img/
        |a.png
        |b.jpg
        |c.jpeg
    |data.json
    |not-to-copy.json
    |not-to-copy.conf
    |index.js
    |index.html
|package.json

If you have a project structure like this add, some scripts to the package.json

{
    ...
    "source": "src/index.html",
    "scripts": {
        "clean-dist": "rm -rf dist && mkdir dist",
        "copy-img": "cp -vR ./src/img ./dist",
        "copy-data": "cp -r src/data.json dist",
        "copy-assets": "cp -r src/assets/* dist",
        "copy-files": "npm run copy-img & npm run copy-assets & npm run copy-data",
        "init": "npm run clean-dist && npm run copy-files",
        "start": "npm run init && parcel",
        "build": "npm run init && parcel build"
    },
    ...
}

This configuration will sequentially run clean-dist and copy-files. The former will delete the dist directory and make the directory again. Then copy-files will copy src/img -> dist/img, src/assets/* -> dist/* and src/data.json -> dist/data.json in parallel. Finally, parcel will be executed.