├── .gitattributes ├── README.md ├── index.js ├── package.json └── stubs ├── .babelrc ├── shims-vue.d.ts └── tsconfig.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Mix v5 - Vue 3 2 | 3 | A Laravel Mix extension for Vue 3, Typescript and JSX. 4 | 5 | Deprecated use [Laravel Mix v6](https://laravel-mix.com/docs) 6 | 7 | ## Usage 8 | 9 | First, install the extension. 10 | 11 | ```bash 12 | npm install laravel-mix-vue3 --save-dev 13 | 14 | //or 15 | 16 | yarn add laravel-mix-vue3 -D 17 | ``` 18 | 19 | Make sure to install the below if Laravel Mix failed to install them 20 | 21 | ``` 22 | npm install @types/webpack-env @vue/compiler-sfc vue-loader@next laravel-mix-vue3 --save-dev 23 | // or 24 | yarn add @types/webpack-env @vue/compiler-sfc vue-loader@next laravel-mix-vue3 -D 25 | ``` 26 | 27 | Then, require it within your `webpack.mix.js` file, like so: 28 | 29 | ### Basic 30 | 31 | ```js 32 | const mix = require("laravel-mix"); 33 | 34 | require("laravel-mix-vue3"); 35 | 36 | mix.vue3("resources/js/app.js", "public/js"); 37 | ``` 38 | 39 | ### Enable Typescript 40 | 41 | ```js 42 | const mix = require("laravel-mix"); 43 | 44 | require("laravel-mix-vue3"); 45 | 46 | mix.vue3("resources/js/app.ts", "public/js", { 47 | typescript: true, 48 | }); 49 | ``` 50 | 51 | ### Enable JSX 52 | 53 | ```js 54 | const mix = require("laravel-mix"); 55 | 56 | require("laravel-mix-vue3"); 57 | 58 | mix.vue3("resources/js/app.jsx", "public/js", { 59 | jsx: true, 60 | }); 61 | ``` 62 | 63 | ### Enable TSX 64 | 65 | ```js 66 | const mix = require("laravel-mix"); 67 | 68 | require("laravel-mix-vue3"); 69 | 70 | mix.vue3("resources/js/app.tsx", "public/js", { 71 | typescript: true, 72 | jsx: true, 73 | }); 74 | ``` 75 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const mix = require("laravel-mix"); 2 | 3 | const { VueLoaderPlugin } = require("vue-loader"); 4 | 5 | let glob = require("glob"); 6 | const fs = require("fs"); 7 | 8 | class Vue3 { 9 | constructor() { 10 | this.toCompile = []; 11 | } 12 | 13 | /** 14 | * The API name for the component. 15 | */ 16 | name() { 17 | return "vue3"; 18 | } 19 | 20 | /** 21 | * Required dependencies for the component. 22 | */ 23 | dependencies() { 24 | let deps = ["@vue/compiler-sfc", "vue-loader@next", "vue@next"]; 25 | 26 | if (this.options.jsx) { 27 | deps.push("@vue/babel-plugin-jsx"); 28 | } 29 | 30 | if (this.options.typescript) { 31 | deps.push("typescript"); 32 | deps.push("ts-loader"); 33 | } 34 | 35 | return deps; 36 | } 37 | 38 | /** 39 | * Register the component. 40 | * 41 | * @param {*} entry 42 | * @param {string} output 43 | */ 44 | register(entry, output, options = { jsx: false, typescript: false }) { 45 | this.options = options; 46 | 47 | if (this.options.jsx && !fs.existsSync(".babelrc")) { 48 | fs.copyFileSync(__dirname + "/stubs/.babelrc", ".babelrc"); 49 | } 50 | 51 | if (this.options.typescript && !fs.existsSync("tsconfig.json")) { 52 | fs.copyFileSync(__dirname + "/stubs/tsconfig.json", "tsconfig.json"); 53 | } 54 | 55 | if (this.options.typescript && !fs.existsSync("shims-vue.d.ts")) { 56 | fs.copyFileSync(__dirname + "/stubs/shims-vue.d.ts", "shims-vue.d.ts"); 57 | } 58 | 59 | if (typeof entry === "string" && entry.includes("*")) { 60 | entry = glob.sync(entry); 61 | } 62 | 63 | entry = [].concat(entry).map((file) => new File(file)); 64 | output = new File(output); 65 | 66 | this.toCompile.push({ entry, output }); 67 | } 68 | 69 | /** 70 | * Assets to append to the webpack entry. 71 | * 72 | * @param {Entry} entry 73 | */ 74 | webpackEntry(entry) { 75 | this.toCompile.forEach((js) => { 76 | entry.addFromOutput( 77 | js.entry.map((file) => file.path()), 78 | js.output, 79 | js.entry[0] 80 | ); 81 | }); 82 | } 83 | 84 | /** 85 | * webpack rules to be appended to the master config. 86 | */ 87 | webpackRules() { 88 | let rules = [ 89 | { 90 | test: /\.vue$/, 91 | use: [ 92 | { 93 | loader: "vue-loader", 94 | }, 95 | ], 96 | }, 97 | 98 | { 99 | test: this.options.jsx ? /\.(js|jsx)$/ : /\.(js)$/, 100 | exclude: /node_modules/, 101 | use: { 102 | loader: "babel-loader", 103 | }, 104 | }, 105 | ]; 106 | 107 | if (this.options.typescript) { 108 | rules.push({ 109 | test: this.options.jsx ? /\.(ts|tsx)$/ : /\.(ts)$/, 110 | exclude: /node_modules/, 111 | use: [ 112 | { 113 | loader: "babel-loader", 114 | options: { babelrc: true }, 115 | }, 116 | { 117 | loader: "ts-loader", 118 | options: { appendTsSuffixTo: [/\.vue$/] }, 119 | }, 120 | ], 121 | }); 122 | } 123 | 124 | return rules; 125 | } 126 | 127 | /** 128 | * Override the generated webpack configuration. 129 | * 130 | * @param {Object} webpackConfig 131 | */ 132 | webpackConfig(webpackConfig) { 133 | delete webpackConfig.resolve.alias["vue$"]; 134 | 135 | webpackConfig.resolve.extensions = [ 136 | "*", 137 | ".js", 138 | ".jsx", 139 | ".vue", 140 | ".ts", 141 | ".tsx", 142 | ]; 143 | 144 | webpackConfig.plugins.push(new VueLoaderPlugin()); 145 | } 146 | } 147 | 148 | mix.extend("vue3", new Vue3()); 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.7.0", 3 | "name": "laravel-mix-vue3", 4 | "description": "A Laravel Mix extension for Vue 3, Typescript and JSX.", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/KABBOUCHI/laravel-mix-vue3.git" 9 | }, 10 | "keywords": [ 11 | "laravel", 12 | "laravel mix", 13 | "mix", 14 | "webpack", 15 | "vue3", 16 | "vue 3", 17 | "jsx", 18 | "tsx", 19 | "typescript" 20 | ], 21 | "author": "Georges KABBOUCHI", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/KABBOUCHI/laravel-mix-vue3/issues" 25 | }, 26 | "homepage": "https://github.com/KABBOUCHI/laravel-mix-vue3#readme", 27 | "peerDependencies": { 28 | "laravel-mix": ">=5.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /stubs/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@vue/babel-plugin-jsx"] 3 | } 4 | -------------------------------------------------------------------------------- /stubs/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import { defineComponent } from "vue"; 3 | const component: ReturnType; 4 | export default component; 5 | } 6 | -------------------------------------------------------------------------------- /stubs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true, 11 | "sourceMap": true, 12 | "baseUrl": ".", 13 | "types": ["webpack-env"], 14 | "paths": { 15 | // "@/*": ["resources/js/*"] 16 | }, 17 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"] 18 | }, 19 | "include": [ 20 | "resources/js/**/*.ts", 21 | "resources/js/**/*.tsx", 22 | "resources/js/**/*.vue" 23 | ], 24 | "exclude": ["node_modules"] 25 | } 26 | --------------------------------------------------------------------------------