WE GOT VITE WORKING LETS FUCKING GOOOOOOOOOOOOO

This commit is contained in:
fero
2024-03-03 01:15:30 -07:00
committed by Elizabeth
parent 5a81ccacac
commit 9cf5466482
14 changed files with 832 additions and 434 deletions

View File

@@ -1,12 +0,0 @@
{
"plugins": [
"babel-plugin-macros",
"styled-components",
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread",
"@babel/proposal-optional-chaining",
"@babel/proposal-nullish-coalescing-operator",
"@babel/syntax-dynamic-import"
],
"presets": ["@babel/typescript", ["@babel/react", { "runtime": "automatic" }]]
}

View File

@@ -1,14 +1,18 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true,
overrides: [
{
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
tsconfigRootDir: './',
},
},
project: './tsconfig.json',
tsconfigRootDir: './',
},
],
settings: {
react: {
pragma: 'React',
@@ -23,11 +27,6 @@ module.exports = {
browser: true,
es6: true,
},
overrides: [
{
files: ['*.ts', '*.tsx'],
},
],
plugins: ['react', 'react-hooks', 'prettier', '@typescript-eslint'],
extends: [
// 'standard',
@@ -38,7 +37,8 @@ module.exports = {
'plugin:jest-dom/recommended',
],
rules: {
'prettier/prettier': 0,
eqeqeq: 'error',
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
// TypeScript can infer this significantly better than eslint ever can.
'react/prop-types': 0,
'react/display-name': 0,
@@ -51,12 +51,7 @@ module.exports = {
// @see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
'no-use-before-define': 0,
'@typescript-eslint/no-use-before-define': 'warn',
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/ban-ts-comment': 0,
},
settings: {
react: {
version: 'detect',
},
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-expect-error': 'allow-with-description' }],
},
};

View File

@@ -7,19 +7,11 @@ use Pterodactyl\Services\Helpers\AssetHashService;
class AssetComposer
{
/**
* AssetComposer constructor.
*/
public function __construct(private AssetHashService $assetHashService)
{
}
/**
* Provide access to the asset service in the views.
*/
public function compose(View $view): void
{
$view->with('asset', $this->assetHashService);
$view->with('siteConfiguration', [
'name' => config('app.name') ?? 'Pterodactyl',
'locale' => config('app.locale') ?? 'en',

View File

@@ -1,117 +0,0 @@
<?php
namespace Pterodactyl\Services\Helpers;
use Illuminate\Support\Arr;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Contracts\Filesystem\Filesystem;
use Pterodactyl\Exceptions\ManifestDoesNotExistException;
class AssetHashService
{
/**
* Location of the manifest file generated by gulp.
*/
public const MANIFEST_PATH = './assets/manifest.json';
private Filesystem $filesystem;
protected static mixed $manifest = null;
/**
* AssetHashService constructor.
*/
public function __construct(FilesystemManager $filesystem)
{
$this->filesystem = $filesystem->createLocalDriver(['root' => public_path()]);
}
/**
* Modify a URL to append the asset hash.
*/
public function url(string $resource): string
{
$file = last(explode('/', $resource));
$data = Arr::get($this->manifest(), $file) ?? $file;
return str_replace($file, Arr::get($data, 'src') ?? $file, $resource);
}
/**
* Return the data integrity hash for a resource.
*/
public function integrity(string $resource): string
{
$file = last(explode('/', $resource));
$data = array_get($this->manifest(), $file, $file);
return Arr::get($data, 'integrity') ?? '';
}
/**
* Return a built CSS import using the provided URL.
*/
public function css(string $resource): string
{
$attributes = [
'href' => $this->url($resource),
'rel' => 'stylesheet preload',
'as' => 'style',
'crossorigin' => 'anonymous',
'referrerpolicy' => 'no-referrer',
];
if (config('pterodactyl.assets.use_hash')) {
$attributes['integrity'] = $this->integrity($resource);
}
$output = '<link';
foreach ($attributes as $key => $value) {
$output .= " $key=\"$value\"";
}
return $output . '>';
}
/**
* Return a built JS import using the provided URL.
*/
public function js(string $resource): string
{
$attributes = [
'src' => $this->url($resource),
'crossorigin' => 'anonymous',
];
if (config('pterodactyl.assets.use_hash')) {
$attributes['integrity'] = $this->integrity($resource);
}
$output = '<script';
foreach ($attributes as $key => $value) {
$output .= " $key=\"$value\"";
}
return $output . '></script>';
}
/**
* Get the asset manifest and store it in the cache for quicker lookups.
*/
protected function manifest(): array
{
if (static::$manifest === null) {
self::$manifest = json_decode(
$this->filesystem->get(self::MANIFEST_PATH),
true
);
}
$manifest = static::$manifest;
if ($manifest === null) {
throw new ManifestDoesNotExistException();
}
return $manifest;
}
}

View File

@@ -6,7 +6,7 @@ module.exports = {
preset: 'ts-jest',
globals: {
'ts-jest': {
isolatedModules: true,
isolatedModules: true,
},
},
moduleFileExtensions: ['js', 'ts', 'tsx', 'd.ts', 'json', 'node'],

839
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,15 @@
{
"name": "pterodactyl-panel",
"engines": {
"node": ">=14"
"node": ">=20.0"
},
"type": "module",
"dependencies": {
"@headlessui/react": "^1.6.4",
"@preact/signals-react": "^1.2.1",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/line-clamp": "^0.4.4",
"@vitejs/plugin-react": "^4.2.1",
"axios": "^0.27.2",
"browserslist": "^4.23.0",
"chart.js": "^3.8.0",
@@ -22,6 +24,7 @@
"events": "^3.0.0",
"formik": "^2.4.5",
"framer-motion": "^11.0.8",
"laravel-vite-plugin": "^1.0.2",
"pathe": "^1.1.2",
"qrcode.react": "^1.0.1",
"react": "^18.2.0",
@@ -38,6 +41,7 @@
"swr": "^2.2.5",
"tailwindcss": "^3.4.1",
"uuid": "^8.3.2",
"vite": "^5.1.4",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0",
"xterm-addon-search": "^0.13.0",
@@ -67,7 +71,7 @@
"@types/debounce": "^1.2.0",
"@types/events": "^3.0.0",
"@types/jest": "^28.1.3",
"@types/node": "^14.11.10",
"@types/node": "^20.11.24",
"@types/qrcode.react": "^1.0.1",
"@types/react": "^17.0.76",
"@types/react-copy-to-clipboard": "^4.3.0",
@@ -124,12 +128,8 @@
"clean": "cd public/assets && find . \\( -name \"*.js\" -o -name \"*.map\" \\) -type f -delete",
"test": "jest",
"lint": "eslint ./resources/scripts/**/*.{ts,tsx} --ext .ts,.tsx",
"//watch": "I set node_env to production because watch does not work otherwise. Too bad!",
"watch": "cross-env NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider ./node_modules/.bin/webpack --watch --progress",
"build": "cross-env NODE_ENV=development NODE_OPTIONS=--openssl-legacy-provider ./node_modules/.bin/webpack --progress",
"build:fast": "cross-env NODE_ENV=development NODE_OPTIONS=--openssl-legacy-provider TYPE_CHECKING=false ./node_modules/.bin/webpack --progress && echo \"\n[!] Type checking was disabled for this build, this may result in runtime errors.\n\"",
"build:production": "cross-env NODE_ENV=production NODE_OPTIONS=--openssl-legacy-provider ./node_modules/.bin/webpack --mode production",
"serve": "npm run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://pterodactyl.test --hot"
"dev": "vite",
"build": "vite build"
},
"browserslist": [
"> 0.5%",
@@ -139,6 +139,7 @@
],
"babelMacros": {
"twin": {
"config": "tailwind.config.cjs",
"preset": "styled-components"
},
"styledComponents": {

View File

@@ -86,6 +86,7 @@ export default () => {
}}
/>
<SubNavigation>
<div>hi 2</div>
<div className='flex flex-row items-center justify-between h-8'>
<Link to={'/'} className='flex shrink-0 h-full w-fit'>
<Logo />

View File

@@ -32,6 +32,9 @@
@yield('assets')
@include('layouts.scripts')
@viteReactRefresh
@vite('resources/scripts/index.tsx')
</head>
<body data-pyro-body class="{{ $css['body'] ?? 'bg-zinc-50' }}">
@section('content')
@@ -39,8 +42,5 @@
@yield('container')
@yield('below-container')
@show
@section('scripts')
{!! $asset->js('main.js') !!}
@show
</body>
</html>

View File

@@ -45,6 +45,6 @@
"stripInternal": true,
"useDefineForClassFields": true
},
"include": ["./resources/scripts/**/*"],
"include": ["./resources/scripts/**/*", "vite.config.ts"],
"exclude": ["node_modules"]
}

58
vite.config.ts Normal file
View File

@@ -0,0 +1,58 @@
import react from '@vitejs/plugin-react';
import laravel from 'laravel-vite-plugin';
import { dirname, resolve } from 'pathe';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vite';
export default defineConfig({
build: {
assetsInlineLimit: 0,
emptyOutDir: true,
// we need to do this because otherwise it will
// generate in .vite/manifest.json, while laravel
// looks in public/build/manifest.json
manifest: 'manifest.json',
outDir: 'public/build',
rollupOptions: {
input: 'resources/scripts/index.tsx',
},
},
define: {
'process.env': {},
'process.platform': null,
'process.version': null,
'process.versions': null,
},
plugins: [
laravel('resources/scripts/index.tsx'),
react({
babel: {
plugins: ['babel-plugin-macros', 'babel-plugin-styled-components'],
},
}),
],
resolve: {
alias: {
'@': resolve(dirname(fileURLToPath(import.meta.url)), 'resources', 'scripts'),
'@definitions': resolve(
dirname(fileURLToPath(import.meta.url)),
'resources',
'scripts',
'api',
'definitions'
),
'@feature': resolve(
dirname(fileURLToPath(import.meta.url)),
'resources',
'scripts',
'components',
'server',
'features'
),
},
},
});

View File

@@ -1,169 +0,0 @@
const path = require('path');
const webpack = require('webpack');
const AssetsManifestPlugin = require('webpack-assets-manifest');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const TerserPlugin = require('terser-webpack-plugin');
const isProduction = process.env.NODE_ENV === 'production';
const typeChecking = process.env.TYPE_CHECKING !== 'false';
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
fallback: {
fs: require.resolve('fs'),
os: require.resolve('os-browserify/browser'),
path: require.resolve('path-browserify'),
},
},
cache: true,
target: 'web',
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? false : process.env.DEVTOOL || 'eval-source-map',
performance: {
hints: false,
},
entry: ['./resources/scripts/index.tsx'],
output: {
path: path.join(__dirname, '/public/assets'),
filename: 'bundle.js', // Simplify filename for development
publicPath: process.env.WEBPACK_PUBLIC_PATH || '/assets/',
crossOriginLoading: 'anonymous',
pathinfo: false,
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules|\.spec\.tsx?$/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
},
// Doesn't work sadly cause our packages need to be polyfilled
// and webpack doesn't feel like doing that ???
// {
// // Match `.js`, `.jsx`, `.ts` or `.tsx` files
// test: /\.[jt]sx?$/,
// exclude: /node_modules|\.spec\.tsx?$/,
// loader: 'esbuild-loader',
// options: {
// // JavaScript version to compile to
// target: 'es2015',
// },
// },
// Why do we need to transpile node_modules? Removing this doesn't
// break builds for me, but I'll keep it just in case. Should be
// faster with swc
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
// fails on production, works on dev
// use: {
// loader: 'swc-loader',
// options: {
// parseMap: true,
// },
// },
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader'], // Simplified CSS loader configuration
},
{
test: /\.(png|jp(e?)g|gif)$/,
loader: 'file-loader',
options: {
name: 'images/[name].[hash:8].[ext]',
},
},
{
test: /\.svg$/,
loader: 'svg-url-loader',
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
alias: {
'@': path.join(__dirname, '/resources/scripts'),
'@definitions': path.join(__dirname, '/resources/scripts/api/definitions'),
'@feature': path.join(__dirname, '/resources/scripts/components/server/features'),
},
symlinks: false,
},
externals: {
moment: 'moment',
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: isProduction ? 'production' : 'development',
DEBUG: isProduction ? 'false' : 'true',
WEBPACK_BUILD_HASH: Date.now().toString(16),
}),
new AssetsManifestPlugin({ writeToDisk: true, publicPath: true, integrity: true, integrityHashes: ['sha384'] }),
typeChecking
? new ForkTsCheckerWebpackPlugin({
typescript: {
mode: 'write-references',
diagnosticOptions: {
semantic: true,
syntactic: true,
},
},
eslint: {
files: `${path.join(__dirname, '/resources/scripts')}/**/*.{ts,tsx}`,
},
})
: null,
process.env.ANALYZE_BUNDLE
? new BundleAnalyzerPlugin({
analyzerHost: '0.0.0.0',
analyzerPort: 8081,
})
: null,
].filter((p) => p),
optimization: {
usedExports: isProduction,
sideEffects: isProduction,
removeEmptyChunks: isProduction,
mergeDuplicateChunks: isProduction,
providedExports: isProduction,
concatenateModules: isProduction,
minimize: isProduction,
minimizer: [
new TerserPlugin({
extractComments: false,
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
watchOptions: {
poll: 1000,
ignored: /node_modules/,
},
devServer: {
hot: true,
port: 3000,
compress: true,
contentBase: path.join(__dirname, '/public'),
publicPath: process.env.WEBPACK_PUBLIC_PATH || '/assets/',
allowedHosts: ['.pterodactyl.test'],
headers: {
'Access-Control-Allow-Origin': '*',
},
},
};