Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Featuring Glob, Excluding Files, and Change Output #16

Merged
merged 13 commits into from
Sep 26, 2024

Conversation

FarhanMS123
Copy link
Contributor

Hi! Thankyou for this plugin. It really fully have all I need.

Currently, I have different issues I want to solve. My case is I want to copy whole root project to output dir withoyt .git, and node_modules. The viteConfig.public can retrieve public files only by single directory, and I thought viteConfig.build.rollupOptions.external can be use to exclude these node_modules and .git from public listing. Unfortunately, I am wrong. So, I come to see this plugins and fully meet my objective.

In this PR, I add some major features:

I've test this on examples React and Solid and works also when dev mode.

But, this PR also has some issues or planned task:

  • Not tested by E2E
  • Bugs on pattern that start by ./ because of auto translate without it
  • Files searching is only string[], it was planned to have more filters and individual output changing such as
import type { Options } from "fast-glob";
export type IAssets = string[] | string | (IConfigExtend & { assets: string | string[]; })[];
export interface IConfigExtend extends Partial<Pick<Options, "ignore" | "dot">> {
    dst?: string | FDst;
}
  • As the api change massively, it would be good to move on to major version 2. (I haven't change the version inside package.json)
  • Documentation is only described inside packages/libs/types.d.ts

@nguyenbatranvan
Copy link
Owner

Thanks for creating this PR!! I'm currently on a trip abroad, will watch it in the next few days!!

@nguyenbatranvan
Copy link
Owner

I'm quite impressed with what you contributed, would there be some further description of those changes? Now I have a look, and see the usage has changed with your PR

@FarhanMS123
Copy link
Contributor Author

FarhanMS123 commented Jun 12, 2024

Thankyou for your support. Perhaps I would tell my use case, and some tricky way that implemented by these features. At the beginning, my use case is copying the root project with ignoring some folders. I thought it could be done by Vite by using this way:

export default defineConfig({
  build: {
    rollupOptions: {
      external: [/\.git/ig, /node_modules/ig],
    },
  },
  publicDir: __dirname,
});

Unfortunately, the build.rollupOptions.external did not works by this reason. So, as I do not want to reinvent the wheel, I search many plugins on awesome awesome-vite and somewhere else on internet. And I comes to you. It meets my objective, and at first it works by what I want it to do. But I have some cases to fullfill, so I open this PR.


  • FEAT: for my first use case, I need this plugin to ignore some folder by pattern, and I implement fast-glob. So, basically, this plugin can do this:
DynamicPublicDirectory(["**"], {
  ignore: [".git", "node_modules"],
})
  • ISSUE: for some reason, the types of the plugin is not correct to satisfy linter. And also for convenience, I recommend configuration to be like this:
import {PluginOption, defineConfig} from 'vite'
import DynamicPublicDirectory from "vite-multiple-assets";

export default defineConfig({
    root: __dirname,
    publicDir: false,
    plugins: [
       // this plugin must be put at last like after Vite or Svelte transformer
        DynamicPublicDirectory([], {
            ssr: false,
        }) as PluginOption,
    ],
})
  • TRICK: then, I realize, the original program also include the name of folder into output directory rather than the content itself. So, for convenience, the beginning name of output file is the start of pattern. For example below, I want to copy all of google-mui fonts in each subfolder, but it MUST has google-mui as [(great-)grand]parent. So just cover the folder name by {\x01,FOLDER_NAME}. By Glob definition, this pattern is used if there is multiple name we want to include. But if we just use {folder_name} or {,folder_name}, it would assume to be literal or assume it includes everything at CWD. Null is also forbidden. So, I use \x01 and assume there is absolutely no one that would have a file or folder name that literally an ASCII of 1.
assets/fonts/google-mui/roboto/roboto-mono.sft
+ assets/fonts/{\x01,google-mui}/**
= google-mui/roboto/roboto-mono.sft
DynamicPublicDirectory(["assets/fonts/{\x01,google-mui}/**"])
  • FEAT: I actually also read all issues and PR to ensure what I done is not "reinventing", and I find this issue Output asset folders at a subdirectory #9 . So, I add feature which user can also rename it. It can either literal string to set different folder, or a function to rename the files.

Caution

It MUST return a POSIX filepath, Slash rather than backslash
RIGHT: dir1/dir2/file.txt
RIGHT: C:/Windows/System32
WRONG: dir1\\dir2\\file.txt

import path from "path/posix"; // NOTE: use posix for relative transformation

// different folder
DynamicPublicDirectory(["public/**"], {
  dst: path.join(__dirname, ".cache"),
})
  • TRICK: it can also programmatically ignore some/all files. And can also edit the list as you wish. When the function is returning false, it ignore the file, but if it returns undefined, it would going as default.
DynamicPublicDirectory(["public/**"], {
  dst: ({ dstFile, filepath, }) => filepath.match(/.jpg$/ig) ? false : undefined,
})
let nonce = false;

DynamicPublicDirectory(["public/**"], {
  dst: ({
    opts: {__dst, ...opts}, __files, // muttable
    dstFile, filepath, baseFile, // useful params to use
  }) => {
    if (!nonce) {
      __files["new-no/existing/file.png"] = "/home/me/Pictures/image.png"
      nonce = true;
    }
  }
})
  • FEAT: pattern and some options of fast-glob can be used inside plugin config
export interface IConfigExtend extends Partial<Pick<Options, "ignore" | "dot">> {
    dst?: string | FDst;
}

export interface IConfig extends 
    IConfigExtend, 
    Partial<Pick<Options, "onlyFiles" | "onlyDirectories" | "cwd" | "markDirectories">> 
{
    __dst?: string; // NOTE: internal destination from parsing rollup write bundlers nor vite config.
    mimeTypes?: IMIME;
    ssr?: boolean;
}
  • TECH: default fast-globs options. As default, this just search files, you override it to find folders, the dirs would be ended by slash /, e.g. dir1/dir2/ and dir3/dir4/file.txt. The returned file would ALWAYS be relative and this is enforced.
({
  ignore: [],
  onlyFiles: true,
  onlyDirectories: false,
  markDirectories: true,
  dot: true,
  absolute: false, // ENFORCED
})
  • REV: some types are parsed and put into types.d.ts
  • DOC: for further options can be seen in types.d.ts
  • DOC: some of research can be seen inside DEVELOPMENT.md
  • ISSUE: If the query is started by ./, e.g. ./public/**, it can't be parsed
  • TECH: because, for enforce parent folder naming features, it would find where is the glob pattern starts. So for the file name public/file.txt would be translated to blic/file.txt which is not exists
  • ISSUE: I still have some doubt on my "slashing" method. There must be a bug.
  • PLAN: For the future, I actually planned to extends assets so it could accept config. For example as below. I just did not implement in this PR because I fear it would be so complex than my own issues I want to solve first.
import path from "path/posix"; // NOTE: use posix for relative transformation

export type IAssets = string[] | string | (IConfigExtend & { assets: string | string[]; })[];

DynamicPublicDirectory([
  "public/**",
  {
    assets: "sample/**.txt",
    ignore: "**photo**"
  },
  {
    assets: ["assets/**", "vars/**"],
    dot: true,
    dst: path.join(__dirname, ".cache")
  },
], {
  dst: ({ dstFile, filepath, }) => filepath.match(/.jpg$/ig) ? false : undefined,
})

@nguyenbatranvan
Copy link
Owner

i tried running e2e for this PR!! It was successful, but there were too many changes from your PR. I need to look into it more closely

@nguyenbatranvan
Copy link
Owner

I took a look, these are great, would there be more documentation about migrating from your old version to your new version on this site: https://github.com/nguyenbatranvan/vite-multiple-assets-doc

@FarhanMS123
Copy link
Contributor Author

Sure. I'll give the update in 3 weeks or more.

@nguyenbatranvan
Copy link
Owner

Sure. I'll give the update in 3 weeks or more.

tks so much!!

@nguyenbatranvan
Copy link
Owner

There have been some changes to the source recently, I have rewritten it to add support for astro.

@FarhanMS123
Copy link
Contributor Author

Hi! Yeah. Sorry for long wait. I've been trying to update the docs. After that, I would try to match up my PR to latest change of this repo.

@nguyenbatranvan
Copy link
Owner

Hi! Yeah. Sorry for long wait. I've been trying to update the docs. After that, I would try to match up my PR to latest change of this repo.

thank you so much! I'm waiting for it

@nguyenbatranvan
Copy link
Owner

maybe!! playwright not work with --stream run dev?

@FarhanMS123
Copy link
Contributor Author

Hi! I am not sure if it is the case. I just have not done with the cleaning yet. Thanks for let me know. Maybe, I would convert this PR to Draft to prevent Actions doing Test Checking for a moment.

@FarhanMS123 FarhanMS123 marked this pull request as draft September 23, 2024 20:44
@FarhanMS123
Copy link
Contributor Author

The documentation should be already done. I am not really doing full cleaning yet. This program still has issue in handling ./, and second I just doing quick patch for Typescript in Astro Integration.

@nguyenbatranvan
Copy link
Owner

The documentation should be already done. I am not really doing full cleaning yet. This program still has issue in handling ./, and second I just doing quick patch for Typescript in Astro Integration.

i see that the tests were successful, maybe merequest completion should be done, thanks for your contribution

@FarhanMS123
Copy link
Contributor Author

Seems I reverted this issue #20 when cleaning server.ts. I would push something first.

@FarhanMS123
Copy link
Contributor Author

Ok, I already check other issues to make sure nothing important reverted. Thank you in advance, this plugin also help me for my current project.

@nguyenbatranvan
Copy link
Owner

Ok, I already check other issues to make sure nothing important reverted. Thank you in advance, this plugin also help me for my current project.

So far, everything is ready?

@FarhanMS123
Copy link
Contributor Author

Yes. It should be ready.

@nguyenbatranvan nguyenbatranvan merged commit d6b0715 into nguyenbatranvan:main Sep 26, 2024
@nguyenbatranvan
Copy link
Owner

Yes. It should be ready.

tks so much!! Released v2.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants