From 98c278b2bbcb9cd7ea1f4ace67374194522b9a1c Mon Sep 17 00:00:00 2001 From: Jeff Sagal Date: Mon, 18 Jul 2022 09:33:46 -0700 Subject: [PATCH] build(vite): replace webpack with Vite, add Typescript (#1594) BREAKING: mixins are no longer exported from the index (and will likely be converted to hooks) --- .editorconfig | 19 - .eslintrc.cjs | 15 + .eslintrc.js | 22 - .github/workflows/release.yml | 15 +- .github/workflows/test.yml | 38 +- .gitignore | 8 +- build/webpack.base.conf.js | 71 - build/webpack.dev.conf.js | 21 - build/webpack.prod.conf.js | 20 - dev/Dev.vue | 5 +- dev/dev.html | 15 - dev/dev.js | 4 +- docs/.vuepress/config.js | 8 + env.d.ts | 1 + index.html | 12 + jsconfig.json | 10 + package.json | 229 +- postcss.config.js | 9 +- src/components/Select.vue | 22 +- src/components/childComponents.js | 4 +- src/index.js | 2 - src/mixins/index.js | 6 +- tests/helpers.js | 21 +- tests/unit/Accessibility.spec.js | 5 +- tests/unit/Ajax.spec.js | 5 +- tests/unit/Autoscroll.spec.js | 14 +- tests/unit/Components.spec.js | 3 +- tests/unit/CreateOption.spec.js | 3 +- tests/unit/Deselecting.spec.js | 9 +- tests/unit/Dropdown.spec.js | 30 +- tests/unit/Filtering.spec.js | 3 +- tests/unit/Keydown.spec.js | 18 +- tests/unit/Labels.spec.js | 43 +- tests/unit/Layout.spec.js | 3 +- tests/unit/OptionComparator.spec.js | 3 +- tests/unit/OptionKey.spec.js | 3 +- tests/unit/ReactiveOptions.spec.js | 27 +- tests/unit/Reduce.spec.js | 7 +- tests/unit/Selectable.spec.js | 3 +- tests/unit/Selecting.spec.js | 11 +- tests/unit/Slots.spec.js | 13 +- tests/unit/Tagging.spec.js | 13 +- tests/unit/TypeAhead.spec.js | 7 +- tests/unit/utility/sortAndStringify.spec.js | 3 +- tests/unit/utility/uniqueId.spec.js | 3 +- tsconfig.app.json | 13 + tsconfig.json | 14 + tsconfig.vite-config.json | 8 + tsconfig.vitest.json | 9 + vite.config.ts | 42 + yarn.lock | 12640 +++++------------- 51 files changed, 3470 insertions(+), 10062 deletions(-) delete mode 100644 .editorconfig create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.js delete mode 100644 build/webpack.base.conf.js delete mode 100644 build/webpack.dev.conf.js delete mode 100644 build/webpack.prod.conf.js delete mode 100644 dev/dev.html create mode 100644 env.d.ts create mode 100644 index.html create mode 100644 jsconfig.json create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.vite-config.json create mode 100644 tsconfig.vitest.json create mode 100644 vite.config.ts diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 3f82792..0000000 --- a/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 4 -trim_trailing_whitespace = true - -[*.{js,vue}] -indent_style = space -indent_size = 2 - -[*.md] -trim_trailing_whitespace = false - -[*.{yml,yaml}] -indent_size = 2 diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..a718c90 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,15 @@ +/* eslint-env node */ +require("@rushstack/eslint-patch/modern-module-resolution"); + +module.exports = { + "root": true, + "extends": [ + "plugin:vue/vue3-essential", + "eslint:recommended", + "@vue/eslint-config-typescript/recommended", + "@vue/eslint-config-prettier" + ], + "env": { + "vue/setup-compiler-macros": true + } +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index f7b4a89..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = { - parser: 'vue-eslint-parser', - parserOptions: { - parser: 'babel-eslint', - sourceType: 'module', - }, - plugins: ['prettier'], - extends: [ - 'plugin:prettier/recommended', - 'plugin:vue/recommended', - 'prettier/vue', - ], - ignorePatterns: [ - '!.*.js', - '!docs/.vuepress', - 'docs/.vuepress/dist', - 'node_modules', - 'dist', - 'coverage', - 'yarn.lock', - ], -} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ac4b6c..cc71f71 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,15 +9,22 @@ jobs: release: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: - node-version: 12 + node-version: 16 + cache: yarn + - uses: actions/cache@v3 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- - name: Install dependencies run: yarn install --frozen-lockfile - - name: Test with Coverage + - name: Test run: yarn test - name: Build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0c94b2c..2cd15a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,16 +4,23 @@ jobs: test: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: - node-version: 12 + node-version: 16 + cache: yarn + - uses: actions/cache@v3 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- - name: Install dependencies run: yarn install --frozen-lockfile - name: Test with Coverage - run: yarn test --coverage --coverageReporters=lcov + run: yarn coverage - name: ESLint run: yarn eslint @@ -26,16 +33,20 @@ jobs: build: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: - node-version: 12 + node-version: 16 + cache: yarn + - uses: actions/cache@v3 + id: yarn-cache + with: + path: '**/node_modules' + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- - name: Install dependencies - run: | - yarn install --frozen-lockfile - cd docs - yarn install --frozen-lockfile + run: yarn install --frozen-lockfile --prefer-offline - name: Build Dist run: yarn build @@ -44,4 +55,7 @@ jobs: run: npx bundlewatch - name: Build Docs - run: yarn build:docs + run: | + cd docs + yarn install --frozen-lockfile --prefer-offline + yarn build diff --git a/.gitignore b/.gitignore index 0c24238..48ad441 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ node_modules .env.*.local # Log files +logs +*.log +pnpm-debug.log* +lerna-debug.log* npm-debug.log* yarn-debug.log* yarn-error.log* @@ -26,5 +30,7 @@ dist test/unit/coverage package-lock.json dev/dist -docs/.vuepress/dist +dist-ssr +*.local .netlify +docs/.vuepress/dist diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js deleted file mode 100644 index 88ebd3c..0000000 --- a/build/webpack.base.conf.js +++ /dev/null @@ -1,71 +0,0 @@ -const path = require('path') -const webpack = require('webpack') -const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin -const MiniCssExtractPlugin = require('mini-css-extract-plugin') - -const env = process.env.NODE_ENV === 'production' ? 'production' : 'development' - -const devtool = env === 'production' ? 'source-map' : 'eval-source-map' - -const extractOrInjectStyles = - env !== 'production' ? 'vue-style-loader' : MiniCssExtractPlugin.loader - -module.exports = { - mode: env, - output: { - path: path.resolve(__dirname, '../dist'), - publicPath: '/', - filename: '[name].js', - }, - devtool, - resolve: { - extensions: ['.js', '.vue'], - alias: { - src: path.resolve(__dirname, '../src'), - assets: path.resolve(__dirname, '../docs/assets'), - mixins: path.resolve(__dirname, '../src/mixins'), - components: path.resolve(__dirname, '../src/components'), - vue$: 'vue/dist/vue.runtime.esm-bundler.js', - }, - }, - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - }, - { - test: /\.js$/, - loader: 'babel-loader', - include: path.resolve(__dirname, '../'), - exclude: /node_modules/, - }, - { - test: /\.css$/i, - use: [ - extractOrInjectStyles, - { - loader: 'css-loader', - options: { importLoaders: 1 }, - }, - 'postcss-loader', - ], - }, - ], - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env': env, - __VUE_OPTIONS_API__: true, - __VUE_PROD_DEVTOOLS__: false, - }), - new MiniCssExtractPlugin({ - filename: 'vue-select.css', - }), - new VueLoaderPlugin(), - ], - stats: { - children: false, - modules: false, - }, -} diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js deleted file mode 100644 index ba23464..0000000 --- a/build/webpack.dev.conf.js +++ /dev/null @@ -1,21 +0,0 @@ -const { merge } = require('webpack-merge') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const baseWebpackConfig = require('./webpack.base.conf') - -module.exports = merge(baseWebpackConfig, { - entry: './dev/dev.js', - devServer: { - open: true, - static: false, - client: { overlay: true }, - watchFiles: ['dev/dev.html'], - }, - stats: false, - plugins: [ - new HtmlWebpackPlugin({ - title: 'dev', - template: './dev/dev.html', - inject: true, - }), - ], -}) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js deleted file mode 100644 index c565e18..0000000 --- a/build/webpack.prod.conf.js +++ /dev/null @@ -1,20 +0,0 @@ -const TerserPlugin = require('terser-webpack-plugin') -const { merge } = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.conf') - -module.exports = merge(baseWebpackConfig, { - entry: './src/index.js', - output: { - filename: 'vue-select.js', - library: 'VueSelect', - libraryTarget: 'umd', - globalObject: "typeof self !== 'undefined' ? self : this", - }, - externals: { - vue: 'vue', - }, - optimization: { - minimize: true, - minimizer: [new TerserPlugin()], - }, -}) diff --git a/dev/Dev.vue b/dev/Dev.vue index fa34401..ab8e964 100644 --- a/dev/Dev.vue +++ b/dev/Dev.vue @@ -5,9 +5,8 @@ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..40548c2 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "@tests/*": ["tests/*"] + } + }, + "exclude": ["node_modules", "dist", "coverage", "docs"] +} diff --git a/package.json b/package.json index 70bf8c8..27de937 100644 --- a/package.json +++ b/package.json @@ -1,138 +1,99 @@ { - "name": "vue-select", - "version": "4.0.0-beta.3", - "description": "Everything you wish the HTML element could do, wrapped up into a lightweight, extensible Vue component.", + "author": "Jeff Sagal ", + "homepage": "https://vue-select.org", + "directories": { + "doc": "docs", + "test": "tests" }, - "moduleNameMapper": { - "^@/(.*)$": "/src/$1" - }, - "snapshotSerializers": [ - "jest-serializer-vue" - ], - "testMatch": [ - "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" - ], - "testURL": "http://localhost/", - "collectCoverage": true, - "collectCoverageFrom": [ - "src/mixins/*.js", - "!src/mixins/index.js", - "src/components/Select.vue", - "!**/node_modules/**" - ], - "coverageReporters": [ - "text" - ] - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - }, - "bundlewatch": { "files": [ - { - "path": "./dist/vue-select.js", - "compression": "none", - "maxSize": "23 KB" - }, - { - "path": "./dist/vue-select.css", - "compression": "none", - "maxSize": "8 KB" - } - ] - } + "dist" + ], + "main": "./dist/vue-select.umd.js", + "module": "./dist/vue-select.es.js", + "exports": { + ".": { + "import": "./dist/vue-select.es.js", + "require": "./dist/vue-select.umd.js" + } + }, + "private": false, + "license": "MIT", + "prepare": "npm run build", + "scripts": { + "dev:docs": "cd docs && yarn serve", + "build:docs": "cd docs && yarn build", + "semantic-release": "semantic-release", + "commit": "git-cz", + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview --port 5050", + "test": "vitest --environment jsdom", + "coverage": "vitest --run --coverage --environment jsdom --silent", + "typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", + "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" + }, + "repository": { + "type": "git", + "url": "https://github.com/sagalbot/vue-select.git" + }, + "peerDependencies": { + "vue": "3.x" + }, + "devDependencies": { + "@rushstack/eslint-patch": "^1.1.4", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^8.0.5", + "@types/jsdom": "^16.2.14", + "@types/node": "^18.0.5", + "@vitejs/plugin-vue": "^3.0.0", + "@vue/eslint-config-prettier": "^7.0.0", + "@vue/eslint-config-typescript": "^11.0.0", + "@vue/test-utils": "^2.0.2", + "@vue/tsconfig": "^0.1.3", + "autoprefixer": "^10.4.7", + "bundlewatch": "^0.3.3", + "c8": "^7.11.3", + "commitizen": "^4.2.5", + "coveralls": "^3.1.1", + "cross-env": "^7.0.3", + "cz-conventional-changelog": "3.3.0", + "eslint": "^8.20.0", + "eslint-plugin-vue": "^9.2.0", + "jsdom": "^20.0.0", + "postcss-nested": "^5.0.6", + "prettier": "^2.7.1", + "semantic-release": "^19.0.3", + "typescript": "^4.7.4", + "vite": "^3.0.0", + "vitest": "^0.18.1", + "vue": "^3.2.37", + "vue-tsc": "^0.38.8" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + }, + "bundlewatch": { + "files": [ + { + "path": "./dist/vue-select.es.js", + "compression": "gzip", + "maxSize": "8 KB" + }, + { + "path": "./dist/vue-select.umd.js", + "compression": "gzip", + "maxSize": "7 KB" + }, + { + "path": "./dist/vue-select.css", + "compression": "gzip", + "maxSize": "2 KB" + } + ] + } } diff --git a/postcss.config.js b/postcss.config.js index c76a907..1f15b1c 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,10 +1,3 @@ module.exports = { - plugins: [ - require('postcss-import'), - require('autoprefixer'), - require('postcss-nested'), - require('cssnano')({ - preset: 'default', - }), - ], + plugins: [require('autoprefixer'), require('postcss-nested')], } diff --git a/src/components/Select.vue b/src/components/Select.vue index 4675a84..ee0ee01 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -136,13 +136,13 @@