vite-mix 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Hugo Rodrigues
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # vite-mix
2
+
3
+ [![npm version](https://img.shields.io/npm/v/vite-mix)](https://www.npmjs.com/package/vite-mix)
4
+ [![npm downloads](https://img.shields.io/npm/dt/vite-mix)](https://www.npmjs.com/package/vite-mix)
5
+ [![License: ISC](https://img.shields.io/badge/license-ISC-blue)](LICENSE)
6
+ [![CI](https://github.com/hugoboss17/vite-mix/actions/workflows/ci.yml/badge.svg)](https://github.com/hugoboss17/vite-mix/actions/workflows/ci.yml)
7
+ [![codecov](https://codecov.io/gh/hugoboss17/vite-mix/graph/badge.svg)](https://codecov.io/gh/hugoboss17/vite-mix)
8
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/hugoboss17/vite-mix/badge)](https://scorecard.dev/viewer/?uri=github.com/hugoboss17/vite-mix)
9
+ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/12098/badge)](https://www.bestpractices.dev/projects/12098)
10
+ [![SLSA Level 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev)
11
+ [![Socket Badge](https://socket.dev/api/badge/npm/package/vite-mix)](https://socket.dev/npm/package/vite-mix)
12
+
13
+ Use Vite with a Laravel Mix-like API.
14
+
15
+ ## Purpose
16
+
17
+ Laravel Mix is no longer maintained. This package helps migrate legacy Mix-style build definitions to Vite with minimal frontend structure changes.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install vite-mix
23
+ ```
24
+
25
+ Peer dependencies (install only what you need):
26
+
27
+ ```bash
28
+ npm install --save-dev vite # required
29
+ npm install --save-dev sass # if using .scss/.sass
30
+ npm install --save-dev @vitejs/plugin-vue # if using Vue 3
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ Replace your `webpack.mix.js` with `vite.config.js` with a Mix-style definition:
36
+
37
+ ```js
38
+ // vite.config.js
39
+ import { defineConfig } from "vite";
40
+ import { mix, viteConfigFromGraph } from "vite-mix";
41
+
42
+ const graph = mix()
43
+ .setPublicPath("public")
44
+ .js("resources/assets/js/app.js", "public/js")
45
+ .vue()
46
+ .sass("resources/assets/sass/app.scss", "public/css")
47
+ .css("resources/assets/css/simple.css", "public/css")
48
+ .copy("resources/assets/images/logo.png", "public/images/logo.png")
49
+ .copyDirectory("resources/assets/fonts", "public/fonts")
50
+ .autoload({ jquery: ["$", "jQuery", "window.jQuery"] })
51
+ .toGraph();
52
+
53
+ export default defineConfig(
54
+ async ({ mode }) => await viteConfigFromGraph(graph, mode),
55
+ );
56
+ ```
57
+
58
+ If you need to set the mode manually (e.g. outside Vite):
59
+
60
+ ```js
61
+ const mode =
62
+ process.env.NODE_ENV === "production" ? "production" : "development";
63
+ await viteConfigFromGraph(graph, mode);
64
+ ```
65
+
66
+ Add scripts to your `package.json`:
67
+
68
+ ```json
69
+ {
70
+ "scripts": {
71
+ "dev": "vite",
72
+ "build": "vite build",
73
+ "watch": "vite build --watch"
74
+ }
75
+ }
76
+ ```
77
+
78
+ Then run:
79
+
80
+ ```bash
81
+ npm run build # production
82
+ npm run watch # watch mode
83
+ npm run dev # dev server
84
+ ```
85
+
86
+ ## Supported API
87
+
88
+ | Method | Description |
89
+ | ---------------------------------- | ----------------------------------------------------------------- |
90
+ | `mix()` | Create a new Mix instance |
91
+ | `.setPublicPath(path)` | Output directory (default: `"public"`) |
92
+ | `.js(src, dest)` | JavaScript/TypeScript entry point |
93
+ | `.vue()` | Enable Vue 3 |
94
+ | `.sass(src, dest)` | Sass/SCSS entry point |
95
+ | `.css(src, dest)` | Plain CSS entry point |
96
+ | `.copy(src, dest)` | Copy a file to the output directory |
97
+ | `.copyDirectory(src, dest)` | Copy a directory to the output directory |
98
+ | `.autoload(map)` | Inject globals (e.g. jQuery, Lodash) |
99
+ | `.toGraph()` | Returns the build graph (pass to `viteConfigFromGraph`) |
100
+ | `viteConfigFromGraph(graph, mode)` | Returns a Vite `InlineConfig` (`mode` from Vite's `defineConfig`) |
101
+
102
+ ## Examples
103
+
104
+ ### Basic JavaScript
105
+
106
+ ```js
107
+ import { defineConfig } from "vite";
108
+ import { mix, viteConfigFromGraph } from "vite-mix";
109
+
110
+ const graph = mix()
111
+ .setPublicPath("public")
112
+ .js("resources/assets/js/app.js", "public/js")
113
+ .toGraph();
114
+
115
+ export default defineConfig(
116
+ async ({ mode }) => await viteConfigFromGraph(graph, mode),
117
+ );
118
+ ```
119
+
120
+ ### Sass / CSS
121
+
122
+ ```js
123
+ mix()
124
+ .setPublicPath("public")
125
+ .sass("resources/assets/sass/app.scss", "public/css")
126
+ .css("resources/assets/css/vendor.css", "public/css")
127
+ .toGraph();
128
+ ```
129
+
130
+ ### Vue 3
131
+
132
+ ```js
133
+ mix()
134
+ .setPublicPath("public")
135
+ .js("resources/assets/js/app.js", "public/js")
136
+ .js("resources/assets/js/admin.js", "public/js")
137
+ .vue()
138
+ .toGraph();
139
+ ```
140
+
141
+ only the second JS import uses Vue
142
+
143
+ ### Autoloading
144
+
145
+ Works with any library, not just jQuery:
146
+
147
+ ```js
148
+ mix()
149
+ .setPublicPath("public")
150
+ .autoload({
151
+ jquery: ["$", "jQuery", "window.jQuery"],
152
+ lodash: ["_"],
153
+ })
154
+ .toGraph();
155
+ ```
156
+
157
+ ### Static Assets
158
+
159
+ ```js
160
+ mix()
161
+ .setPublicPath("public")
162
+ .copy("resources/assets/images/logo.png", "public/images/logo.png")
163
+ .copyDirectory("resources/assets/fonts", "public/fonts")
164
+ .toGraph();
165
+ ```
166
+
167
+ ### Full Example
168
+
169
+ ```js
170
+ // vite.config.js
171
+ import { defineConfig } from "vite";
172
+ import { mix, viteConfigFromGraph } from "vite-mix";
173
+
174
+ const graph = mix()
175
+ .setPublicPath("public")
176
+ .js("resources/assets/js/app.js", "public/js")
177
+ .vue()
178
+ .sass("resources/assets/sass/app.scss", "public/css")
179
+ .css("resources/assets/css/vendor.css", "public/css")
180
+ .autoload({
181
+ jquery: ["$", "jQuery", "window.jQuery"],
182
+ lodash: ["_"],
183
+ })
184
+ .copy("resources/assets/images/logo.png", "public/images/logo.png")
185
+ .copyDirectory("resources/assets/fonts", "public/fonts")
186
+ .toGraph();
187
+
188
+ export default defineConfig(
189
+ async ({ mode }) => await viteConfigFromGraph(graph, mode),
190
+ );
191
+ ```
192
+
193
+ ## Webpack compatibility handled
194
+
195
+ - Sass `~` imports — `@import "~bootstrap-sass/assets/stylesheets/bootstrap"`
196
+ - Extensionless Vue imports — `import Component from "../Component"`
197
+ - Directory Vue imports resolving to `index.vue`
198
+ - Legacy bare asset paths in templates resolving from `resources/assets`
199
+
200
+ ## Contributing
201
+
202
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -0,0 +1,50 @@
1
+ import { InlineConfig } from 'vite';
2
+
3
+ declare function viteConfigFromGraph(graph: MixGraph, mode: string): Promise<InlineConfig>;
4
+
5
+ type CopyTarget = {
6
+ src: string;
7
+ dest: string;
8
+ rename?: string;
9
+ };
10
+ type CopyDirTarget = {
11
+ src: string;
12
+ dest: string;
13
+ };
14
+ type CssEntry = {
15
+ src: string;
16
+ destDir: string;
17
+ };
18
+ type JsEntry = {
19
+ src: string;
20
+ destDirOrFile: string;
21
+ };
22
+ type MixGraph = {
23
+ publicPath: string;
24
+ js: JsEntry[];
25
+ css: CssEntry[];
26
+ sass: Array<{
27
+ src: string;
28
+ destDir: string;
29
+ }>;
30
+ copies: CopyTarget[];
31
+ copyDirs: CopyDirTarget[];
32
+ autoload: Record<string, string[]>;
33
+ vue: boolean;
34
+ };
35
+ declare class Mix {
36
+ private graph;
37
+ constructor();
38
+ setPublicPath(p: string): this;
39
+ js(src: string, dest: string): this;
40
+ vue(): this;
41
+ sass(src: string, dest: string): this;
42
+ css(src: string, destDir: string): this;
43
+ copy(src: string, dest: string): this;
44
+ copyDirectory(src: string, dest: string): this;
45
+ autoload(map: Record<string, string[]>): this;
46
+ toGraph(): MixGraph;
47
+ }
48
+ declare function mix(): Mix;
49
+
50
+ export { type CopyDirTarget, type CopyTarget, type CssEntry, type JsEntry, Mix, type MixGraph, mix, viteConfigFromGraph };
package/dist/index.js ADDED
@@ -0,0 +1,342 @@
1
+ // src/index.ts
2
+ import path2 from "path";
3
+
4
+ // src/driver-vite.ts
5
+ import path from "path";
6
+ import fs from "fs";
7
+ import vue from "@vitejs/plugin-vue";
8
+ function relKeyFromResources(file) {
9
+ return file.replace(/^resources\/assets\/(js|css|sass)\//, "").replace(/\.(js|css|scss|sass)$/, "");
10
+ }
11
+ function ensurePosix(p) {
12
+ return p.split(path.sep).join("/");
13
+ }
14
+ function escapeRegExp(s) {
15
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
16
+ }
17
+ var VALID_IDENT = /^[a-zA-Z_$][\w$]*(\.[a-zA-Z_$][\w$]*)*$/;
18
+ var VALID_MODULE = /^[@a-zA-Z][\w./@-]*$/;
19
+ function hasFile(p) {
20
+ try {
21
+ return fs.statSync(p).isFile();
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+ function hasDir(p) {
27
+ try {
28
+ return fs.statSync(p).isDirectory();
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+ function isBareAssetImport(source) {
34
+ if (source.startsWith(".") || source.startsWith("/") || source.startsWith("@")) return false;
35
+ if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(source)) return false;
36
+ const sourcePath = source.split("?")[0].split("#")[0];
37
+ if (!sourcePath.includes("/")) return false;
38
+ return /\.(png|jpe?g|gif|svg|webp|avif|ico|bmp|tiff|woff2?|eot|ttf|otf)$/i.test(sourcePath);
39
+ }
40
+ function webpackCompatResolvePlugin() {
41
+ return {
42
+ name: "mix-webpack-compat-resolve",
43
+ enforce: "pre",
44
+ resolveId(source, importer) {
45
+ if (!importer) return null;
46
+ const isRelative = source.startsWith(".");
47
+ if (isRelative && !path.extname(source)) {
48
+ const importerPath = importer.split("?")[0];
49
+ const baseDir = path.dirname(importerPath);
50
+ const abs = path.resolve(baseDir, source);
51
+ const vueSibling = `${abs}.vue`;
52
+ if (hasFile(vueSibling)) return vueSibling;
53
+ if (hasDir(abs)) {
54
+ const vueIndex = path.join(abs, "index.vue");
55
+ if (hasFile(vueIndex)) return vueIndex;
56
+ }
57
+ const parentDir = path.dirname(abs);
58
+ if (path.basename(abs) === path.basename(parentDir)) {
59
+ const parentIndexVue = path.join(parentDir, "index.vue");
60
+ if (hasFile(parentIndexVue)) return parentIndexVue;
61
+ }
62
+ }
63
+ if (isBareAssetImport(source)) {
64
+ const sourcePath = source.split("?")[0].split("#")[0];
65
+ const candidates = [path.resolve(process.cwd(), "resources/assets", sourcePath), path.resolve(process.cwd(), "resources", sourcePath)];
66
+ for (const candidate of candidates) {
67
+ if (hasFile(candidate)) return candidate;
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ };
73
+ }
74
+ function autoloadPlugin(identMap) {
75
+ const patterns = Object.entries(identMap).map(([ident, module]) => {
76
+ if (!VALID_IDENT.test(ident)) throw new Error(`Invalid autoload identifier: ${ident}`);
77
+ if (!VALID_MODULE.test(module)) throw new Error(`Invalid autoload module: ${module}`);
78
+ return {
79
+ ident,
80
+ module,
81
+ localName: ident.startsWith("window.") ? ident.slice(7) : ident,
82
+ isWindow: ident.startsWith("window."),
83
+ regex: ident.startsWith("window.") ? null : new RegExp(`(?<![.\\w$])${escapeRegExp(ident)}(?![\\w$])`)
84
+ };
85
+ });
86
+ return {
87
+ name: "mix-inject",
88
+ enforce: "post",
89
+ transform(code, id) {
90
+ if (id.includes("node_modules")) return;
91
+ if (!/\.[jt]sx?$/.test(id.split("?")[0])) return;
92
+ const toAdd = [];
93
+ const seen = /* @__PURE__ */ new Set();
94
+ for (const { ident, module, localName, isWindow, regex } of patterns) {
95
+ if (seen.has(localName)) continue;
96
+ if (code.includes(`from '${module}'`) || code.includes(`from "${module}"`) || code.includes(`require('${module}')`) || code.includes(`require("${module}")`))
97
+ continue;
98
+ const used = isWindow ? code.includes(ident) : regex.test(code);
99
+ if (used) {
100
+ toAdd.push(`import ${localName} from '${module}';`);
101
+ seen.add(localName);
102
+ }
103
+ }
104
+ if (!toAdd.length) return;
105
+ return { code: toAdd.join("\n") + "\n" + code, map: null };
106
+ }
107
+ };
108
+ }
109
+ async function collectFiles(dir) {
110
+ const entries = await fs.promises.readdir(dir, { recursive: true, withFileTypes: true });
111
+ return entries.filter((e) => e.isFile()).map((e) => {
112
+ const abs = path.join(e.parentPath, e.name);
113
+ return { abs, rel: path.relative(dir, abs) };
114
+ });
115
+ }
116
+ function safePath(base, untrusted) {
117
+ const resolved = path.resolve(base, untrusted);
118
+ return resolved.startsWith(base + path.sep) ? resolved : null;
119
+ }
120
+ function outputPath(dest, filename) {
121
+ return dest && dest !== "." ? `${dest}/${filename}` : filename;
122
+ }
123
+ function staticCopyPlugin(targets) {
124
+ return {
125
+ name: "mix-static-copy",
126
+ async buildStart() {
127
+ for (const { src, dest, rename } of targets) {
128
+ try {
129
+ if (src.endsWith("/**/*")) {
130
+ const srcDir = src.slice(0, -5);
131
+ for (const { abs, rel } of await collectFiles(srcDir)) {
132
+ this.emitFile({ type: "asset", fileName: outputPath(dest, rel), source: await fs.promises.readFile(abs) });
133
+ }
134
+ } else {
135
+ const filename = rename ?? path.basename(src);
136
+ this.emitFile({ type: "asset", fileName: outputPath(dest, filename), source: await fs.promises.readFile(src) });
137
+ }
138
+ } catch (err) {
139
+ if (err.code !== "ENOENT") throw err;
140
+ }
141
+ }
142
+ },
143
+ configureServer(server) {
144
+ server.middlewares.use((req, res, next) => {
145
+ const url = decodeURIComponent(req.url?.split("?")[0] ?? "");
146
+ for (const { src, dest, rename } of targets) {
147
+ if (src.endsWith("/**/*")) {
148
+ const prefix = `/${dest}/`;
149
+ if (url.startsWith(prefix)) {
150
+ const srcDir = path.resolve(src.slice(0, -5));
151
+ const file = safePath(srcDir, url.slice(prefix.length));
152
+ if (!file) {
153
+ next();
154
+ return;
155
+ }
156
+ fs.promises.readFile(file).then((content) => res.end(content)).catch(() => next());
157
+ return;
158
+ }
159
+ } else {
160
+ const filename = rename ?? path.basename(src);
161
+ if (url === `/${outputPath(dest, filename)}`) {
162
+ fs.promises.readFile(src).then((content) => res.end(content)).catch(() => next());
163
+ return;
164
+ }
165
+ }
166
+ }
167
+ next();
168
+ });
169
+ }
170
+ };
171
+ }
172
+ async function viteConfigFromGraph(graph, mode) {
173
+ const isProd = mode === "production";
174
+ const input = {};
175
+ for (const e of graph.js) {
176
+ input[relKeyFromResources(e.src)] = path.resolve(e.src);
177
+ }
178
+ for (const e of graph.sass) {
179
+ input[relKeyFromResources(e.src)] = path.resolve(e.src);
180
+ }
181
+ for (const e of graph.css) {
182
+ input[relKeyFromResources(e.src)] = path.resolve(e.src);
183
+ }
184
+ const staticTargets = [];
185
+ const resolvedPublic = path.resolve(graph.publicPath);
186
+ const publicPrefixRe = new RegExp(`^${escapeRegExp(ensurePosix(graph.publicPath))}/?`);
187
+ function guardDest(dest) {
188
+ const resolved = path.resolve(graph.publicPath, dest);
189
+ if (resolved !== resolvedPublic && !resolved.startsWith(resolvedPublic + path.sep)) {
190
+ throw new Error(`copy destination escapes publicPath: ${dest}`);
191
+ }
192
+ }
193
+ for (const c of graph.copies) {
194
+ const normalizedDest = ensurePosix(c.dest).replace(publicPrefixRe, "");
195
+ guardDest(normalizedDest);
196
+ const destDir = path.posix.dirname(normalizedDest);
197
+ const base = path.posix.basename(normalizedDest);
198
+ const hasExt = /\.[a-z0-9]+$/i.test(base);
199
+ staticTargets.push({
200
+ src: ensurePosix(c.src),
201
+ dest: hasExt ? destDir : normalizedDest,
202
+ ...hasExt ? { rename: base } : {}
203
+ });
204
+ }
205
+ for (const cd of graph.copyDirs) {
206
+ const normalizedDest = ensurePosix(cd.dest).replace(publicPrefixRe, "");
207
+ guardDest(normalizedDest);
208
+ staticTargets.push({
209
+ src: ensurePosix(cd.src) + "/**/*",
210
+ dest: normalizedDest
211
+ });
212
+ }
213
+ const autoloadMap = {};
214
+ for (const [module, identifiers] of Object.entries(graph.autoload)) {
215
+ for (const ident of identifiers) {
216
+ autoloadMap[ident] = module;
217
+ }
218
+ }
219
+ const plugins = [webpackCompatResolvePlugin()];
220
+ if (graph.vue) {
221
+ plugins.push(vue());
222
+ }
223
+ if (Object.keys(autoloadMap).length) {
224
+ plugins.push(autoloadPlugin(autoloadMap));
225
+ }
226
+ if (staticTargets.length) {
227
+ plugins.push(staticCopyPlugin(staticTargets));
228
+ }
229
+ return {
230
+ resolve: {
231
+ extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json", ".vue"],
232
+ alias: [{ find: /^~(.*)$/, replacement: "$1" }]
233
+ },
234
+ plugins,
235
+ build: {
236
+ manifest: true,
237
+ outDir: graph.publicPath,
238
+ emptyOutDir: false,
239
+ assetsDir: "",
240
+ rollupOptions: {
241
+ input,
242
+ output: isProd ? {
243
+ entryFileNames: `js/[name]-[hash].js`,
244
+ assetFileNames: (assetInfo) => {
245
+ const name = assetInfo.names[0] || "";
246
+ if (name.endsWith(".css")) return `css/[name]-[hash][extname]`;
247
+ return `assets/[name]-[hash][extname]`;
248
+ }
249
+ } : {
250
+ entryFileNames: `js/[name].js`,
251
+ assetFileNames: (assetInfo) => {
252
+ const name = assetInfo.names[0] || "";
253
+ if (name.endsWith(".css")) return `css/${name}`;
254
+ return `assets/${name}`;
255
+ }
256
+ }
257
+ }
258
+ },
259
+ server: {
260
+ strictPort: true
261
+ }
262
+ };
263
+ }
264
+
265
+ // src/index.ts
266
+ function normalizePublicPath(p) {
267
+ let end = p.length;
268
+ while (end > 0 && p[end - 1] === "/") end--;
269
+ return p.slice(0, end);
270
+ }
271
+ var Mix = class {
272
+ graph;
273
+ constructor() {
274
+ this.graph = {
275
+ publicPath: "public",
276
+ js: [],
277
+ css: [],
278
+ sass: [],
279
+ copies: [],
280
+ copyDirs: [],
281
+ autoload: {},
282
+ vue: false
283
+ };
284
+ }
285
+ setPublicPath(p) {
286
+ const normalized = normalizePublicPath(p);
287
+ const resolved = path2.resolve(process.cwd(), normalized);
288
+ if (resolved !== process.cwd() && !resolved.startsWith(process.cwd() + path2.sep)) {
289
+ throw new Error(`publicPath must be within the project directory: ${p}`);
290
+ }
291
+ this.graph.publicPath = normalized;
292
+ return this;
293
+ }
294
+ js(src, dest) {
295
+ this.graph.js.push({ src, destDirOrFile: dest });
296
+ return this;
297
+ }
298
+ vue() {
299
+ this.graph.vue = true;
300
+ return this;
301
+ }
302
+ sass(src, dest) {
303
+ this.graph.sass.push({ src, destDir: dest });
304
+ return this;
305
+ }
306
+ css(src, destDir) {
307
+ this.graph.css.push({ src, destDir });
308
+ return this;
309
+ }
310
+ copy(src, dest) {
311
+ this.graph.copies.push({ src, dest });
312
+ return this;
313
+ }
314
+ copyDirectory(src, dest) {
315
+ this.graph.copyDirs.push({ src, dest });
316
+ return this;
317
+ }
318
+ autoload(map) {
319
+ this.graph.autoload = { ...this.graph.autoload, ...map };
320
+ return this;
321
+ }
322
+ toGraph() {
323
+ return {
324
+ publicPath: this.graph.publicPath,
325
+ js: this.graph.js.map((entry) => ({ ...entry })),
326
+ css: this.graph.css.map((entry) => ({ ...entry })),
327
+ sass: this.graph.sass.map((entry) => ({ ...entry })),
328
+ copies: this.graph.copies.map((entry) => ({ ...entry })),
329
+ copyDirs: this.graph.copyDirs.map((entry) => ({ ...entry })),
330
+ autoload: Object.fromEntries(Object.entries(this.graph.autoload).map(([key, values]) => [key, [...values]])),
331
+ vue: this.graph.vue
332
+ };
333
+ }
334
+ };
335
+ function mix() {
336
+ return new Mix();
337
+ }
338
+ export {
339
+ Mix,
340
+ mix,
341
+ viteConfigFromGraph
342
+ };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "vite-mix",
3
+ "version": "0.7.3",
4
+ "description": "Use Vite as Laravel Mix",
5
+ "keywords": [
6
+ "vite",
7
+ "laravel",
8
+ "mix",
9
+ "laravel-mix",
10
+ "webpack",
11
+ "build-tool"
12
+ ],
13
+ "author": {
14
+ "name": "Hugo Rodrigues",
15
+ "url": "https://github.com/hugoboss17"
16
+ },
17
+ "license": "ISC",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/hugoboss17/vite-mix.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/hugoboss17/vite-mix/issues"
24
+ },
25
+ "type": "module",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "engines": {
34
+ "node": ">=24"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "exports": {
40
+ ".": {
41
+ "types": "./dist/index.d.ts",
42
+ "import": "./dist/index.js"
43
+ }
44
+ },
45
+ "scripts": {
46
+ "dev": "tsup --watch",
47
+ "build": "tsup",
48
+ "test": "vitest run",
49
+ "test:coverage": "vitest run --coverage",
50
+ "verify:pack": "node scripts/verify-pack.ts",
51
+ "check:lockfile": "node scripts/check-lockfile-change.ts",
52
+ "prepack": "npm run build && npm run verify:pack",
53
+ "lint": "node -e \"console.log('add eslint if you want')\"",
54
+ "prepare": "pre-commit install || true"
55
+ },
56
+ "dependencies": {},
57
+ "peerDependencies": {
58
+ "@vitejs/plugin-vue": "^6.0.0",
59
+ "sass": "^1.0.0",
60
+ "vite": "^7.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "25.3.5",
64
+ "@vitest/coverage-v8": "4.0.18",
65
+ "tsup": "8.5.1",
66
+ "typescript": "5.9.3",
67
+ "vite": "7.3.1",
68
+ "vitest": "4.0.18"
69
+ }
70
+ }