First commit

This commit is contained in:
Frank Delaguila
2022-03-12 18:29:49 -07:00
parent 2b0a031e84
commit 7f7415e48e
10 changed files with 406 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.vscode
node_modules/
package-lock.json
dist/
.DS_Store

42
package.json Normal file
View File

@@ -0,0 +1,42 @@
{
"name": "portfolio",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node ./server.js",
"build": "NODE_ENV=production webpack --config webpack.prod.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.17.5",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"babel-loader": "^8.2.3",
"clean-webpack-plugin": "^4.0.0",
"css-minimizer-webpack-plugin": "^3.4.1",
"express": "^4.17.3",
"html-critical-webpack-plugin": "^2.1.0",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"image-minimizer-webpack-plugin": "^3.2.3",
"mini-css-extract-plugin": "^2.6.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-middleware": "^5.3.1",
"webpack-hot-middleware": "^2.25.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@react-three/fiber": "^7.0.26",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"three": "^0.138.3"
}
}

32
server.js Normal file
View File

@@ -0,0 +1,32 @@
const path = require( 'path' );
const express = require( 'express' );
const webpack = require( 'webpack' );
const webpackDevMiddleware = require( 'webpack-dev-middleware' );
const webpackHotMiddleware = require( 'webpack-hot-middleware' );
const app = express();
const config = require('./webpack.dev.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
writeToDisk: true,
})
);
app.use( webpackHotMiddleware(compiler, {
noInfo: true,
quiet: true
}) );
app.get( '/*', function(req, res) {
res.sendFile( 'index.html', {root: path.join( __dirname, './dist/')});
} );
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});

39
src/components/App.jsx Normal file
View File

@@ -0,0 +1,39 @@
import '../styles/styles.scss';
import { useRef, useState } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
const Box = (props) => {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => (ref.current.rotation.x += 0.01))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
};
const App = () => {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
);
};
export default App;

10
src/scripts/app.js Normal file
View File

@@ -0,0 +1,10 @@
import { render } from 'react-dom';
import App from '../components/App';
render(
<App />,
document.getElementById("root") );
if (module['hot']) {
module['hot'].accept();
}

3
src/styles/styles.scss Normal file
View File

@@ -0,0 +1,3 @@
main {
background-color: black;
}

12
src/views/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<main id="root"></main>
</body>
</html>

125
webpack.common.js Normal file
View File

@@ -0,0 +1,125 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
// let htmlPageNames = [];
// let multipleHtmlPlugins = htmlPageNames.map(name => {
// return new HtmlWebpackPlugin({
// template: `./src/views/${name}.html`, // relative path to the HTML files
// filename: `${name}.html`, // output HTML files
// chunks: [`${name}`] // respective JS files
// })
// });
module.exports = {
resolve: {
extensions: ['.js', '.jsx'],
},
module: {
rules: [
// HTML
{
test: /\.html$/,
use: {
loader: 'html-loader',
},
},
// JS
{
test: /\.jsx?$/i,
exclude: /node_modules/,
include: path.resolve(__dirname, 'src'),
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
['@babel/preset-react', { runtime: 'automatic' }],
],
},
},
},
// CSS
{
test: /\.s[ac]ss$/i,
use: [
MiniCSSExtractPlugin.loader,
'css-loader',
'postcss-loader',
'resolve-url-loader',
'sass-loader',
],
},
// Images
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
},
// {
// test: /\.(jpg|png|gif|svg)$/,
// use: {
// loader: 'url-loader'
// }
// },
// {
// test: /\.(jpg|png|gif|svg)$/,
// use:
// [
// {
// loader: 'file-loader',
// options:
// {
// outputPath: './assets/images/'
// }
// }
// ]
// },
// Fonts
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
// {
// test: /\.(ttf|eot|woff|woff2)$/,
// use:
// [
// {
// loader: 'file-loader',
// options:
// {
// outputPath: './assets/fonts/'
// }
// }
// ]
// }
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './src/views/index.html'),
inject: 'body',
}),
],
optimization: {
moduleIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};

60
webpack.dev.js Normal file
View File

@@ -0,0 +1,60 @@
const { merge } = require('webpack-merge');
const webpack = require( 'webpack' );
const commonConfiguration = require('./webpack.common.js');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const path = require('path');
const hotMiddlewareScript =
'webpack-hot-middleware/client?reload=true';
module.exports = merge(commonConfiguration, {
mode: 'development',
entry: {
portfolio: [hotMiddlewareScript, './src/scripts/app.js'],
},
output: {
filename: 'js/[name].[contenthash].js',
path: path.resolve(__dirname, './dist'),
publicPath: '/',
clean: true,
// hotUpdateChunkFilename: 'hot/hot-update.js',
// hotUpdateMainFilename: 'hot/hot-update.json'
},
devtool: 'source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCSSExtractPlugin({
filename: 'css/[name].[contenthash].css',
}),
// new ImageMinimizerPlugin({
// minimizerOptions: {
// // Lossless optimization with custom option
// // Feel free to experiment with options for better result for you
// plugins: [
// ['gifsicle', { interlaced: true }],
// ['jpegtran', { progressive: true }],
// ['optipng', { optimizationLevel: 5 }],
// // Svgo configuration here https://github.com/svg/svgo#configuration
// [
// 'svgo',
// {
// plugins: [
// {
// name: 'removeViewBox',
// active: false,
// },
// {
// name: 'addAttributesToSVGElement',
// params: {
// attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
// },
// },
// ],
// },
// ],
// ],
// },
// }),
]
});

78
webpack.prod.js Normal file
View File

@@ -0,0 +1,78 @@
const { merge } = require('webpack-merge');
const commonConfiguration = require('./webpack.common.js');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const HtmlCriticalPlugin = require('html-critical-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = merge(commonConfiguration, {
mode: 'production',
entry: {
popshop: path.resolve(__dirname, './src/scripts/app.js'),
},
devtool: 'source-map',
output: {
filename: 'js/[name].[contenthash].js',
path: path.resolve(__dirname, './dist'),
clean: true,
assetModuleFilename: 'assets/images/[name][ext][query]',
},
plugins: [
new CleanWebpackPlugin(),
new MiniCSSExtractPlugin({
filename: 'css/[name].[contenthash].css',
}),
// new ImageMinimizerPlugin({
// minimizerOptions: {
// // Lossless optimization with custom option
// // Feel free to experiment with options for better result for you
// plugins: [
// ['gifsicle', { interlaced: true }],
// ['jpegtran', { progressive: true }],
// ['optipng', { optimizationLevel: 5 }],
// // Svgo configuration here https://github.com/svg/svgo#configuration
// [
// 'svgo',
// {
// plugins: [
// {
// name: 'removeViewBox',
// active: false,
// },
// {
// name: 'addAttributesToSVGElement',
// params: {
// attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
// },
// },
// ],
// },
// ],
// ],
// },
// }),
new HtmlCriticalPlugin({
base: path.join(path.resolve(__dirname), 'dist/'),
src: 'index.html',
dest: 'index.html',
inline: true,
minify: true,
extract: true,
width: 375,
height: 565,
penthouse: {
blockJSRequests: false,
},
}),
],
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
parallel: true,
}),
],
},
});