-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
231 changed files
with
19,735 additions
and
335 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"extends": [ | ||
"../../.eslintrc.json", | ||
"react-app", | ||
"next/core-web-vitals", | ||
"plugin:@next/next/recommended", | ||
"plugin:storybook/recommended", | ||
"plugin:@tanstack/eslint-plugin-query/recommended" | ||
], | ||
"plugins": ["jam3", "promise", "@tanstack/query"], | ||
"settings": { | ||
"react": { | ||
"version": "detect" | ||
}, | ||
"import/resolver": { | ||
"alias": { | ||
"map": [["@", "./src"]] | ||
} | ||
} | ||
}, | ||
"rules": { | ||
"jsx-a11y/anchor-has-content": "off", | ||
"jsx-a11y/heading-has-content": "off", | ||
"import/no-webpack-loader-syntax": "off", | ||
"import/no-anonymous-default-export": "off", | ||
"import/no-unresolved": ["error", { "ignore": ["svg-inline-loader", "@"] }], | ||
"import/named": "error", | ||
"import/default": "error", | ||
"import/first": "error", | ||
"simple-import-sort/exports": "warn", | ||
"curly": [2, "multi-line", "consistent"], | ||
"no-var": "error", | ||
"prettier/prettier": "warn", | ||
"promise/param-names": "error", | ||
"promise/no-return-wrap": "error", | ||
"jsx-a11y/href-no-hash": "off", | ||
"jam3/no-sanitizer-with-danger": [ | ||
2, | ||
{ | ||
"wrapperName": ["sanitizer"] | ||
} | ||
], | ||
"jam3/forbid-methods": 2, | ||
"no-console": "off", | ||
"jsx-a11y/anchor-is-valid": [ | ||
"error", | ||
{ | ||
"components": ["Link"], | ||
"specialLink": ["hrefLeft", "hrefRight"], | ||
"aspects": ["invalidHref", "preferButton"] | ||
} | ||
], | ||
"react-hooks/rules-of-hooks": "error", | ||
"react-hooks/exhaustive-deps": "error", | ||
"@next/next/no-img-element": "off", | ||
"@typescript-eslint/no-explicit-any": ["error"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules/ | ||
dist-zipped/ | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
FXHASH Generative Token webpack boilerplate | ||
================ | ||
|
||
A boilerplate to automate and ease the creation of Generative Tokens on fxhash. This project uses [webpack](https://webpack.js.org/) and [webpack-dev-server](https://github.com/webpack/webpack-dev-server) to improve the development and deployment experience. | ||
|
||
Before diving into the development of your token, we recommend reading the [Guide to mint a Generative Token](https://fxhash.xyz/articles/guide-mint-generative-token) to get some understanding of the process. | ||
|
||
If you are looking for a simpler boilerplate, you can use the [fxhash simple boilerplate](https://github.com/fxhash/fxhash-simple-boilerplate) instead. | ||
|
||
|
||
# Scope of this project | ||
|
||
* provide a local environment in which you can iterate and use modern features from the javascript ecosystem | ||
* automate the creation of a .zip file ready to be uploaded on fxhash | ||
|
||
|
||
# How to use | ||
|
||
You will need to have [nodejs](https://nodejs.org/) installed. | ||
|
||
## Installation | ||
|
||
> First, make sure that your node version is >= 14 | ||
Clone the repository on your machine and move to the directory | ||
```sh | ||
$ git clone https://github.com/fxhash/fxhash-webpack-boilerplate.git your_folder && cd your_folder | ||
``` | ||
|
||
Install the packages required for the local environment | ||
```sh | ||
$ npm i | ||
``` | ||
|
||
## Start local environment | ||
|
||
```sh | ||
$ npm start | ||
``` | ||
|
||
This last command will start a local http server with [live reloading](https://webpack.js.org/configuration/dev-server/#devserverlivereload) enabled so that you can iterate faster on your projects. Open [http://localhost:8080](http://localhost:8080) to see your project in the browser. | ||
|
||
## Build | ||
|
||
```sh | ||
$ npm run build | ||
``` | ||
|
||
Will bundle your js dependencies into a single minified `bundle.js` file, move your files from the `public/` to the `dist/` folder, and link the `bundle.js` with the `index.html`. | ||
|
||
**Moreover, it will create a `dist-zipped/project.zip` file which can be directly imported on fxhash**. | ||
|
||
# Develop your token | ||
|
||
Once the environment is started, you can edit the `src/index.js` file to start building your artwork. The `index.html` file is located in the `public/` folder. | ||
|
||
You can import libraries using `npm` or by adding the library file in the `public/` folder and link those using relative paths in the `index.html`. | ||
|
||
Any file in the `public/` folder will be added to the final project. | ||
|
||
## fxhash snippet | ||
|
||
fxhash requires you to use a javascript code snippet so that the platform can inject some code when tokens will be generated from your Generative Token. The code snippet is already in the `index.html` file of this boilerplate, so you don't have to add it yourself. | ||
|
||
**During the development stages, the snippet will generate a random hash each time the page is refreshed**. This way, it helps you reproduce the conditions in which your token will be executed on fxhash. | ||
|
||
It creates 3 variables: | ||
- `fxhash`: a random 64 characters hexadecimal string. This particular variable will be hardcoded with a static hash when someone mints a token from your GT | ||
- `fxrand()`: a PRNG function that generates deterministic PRN between 0 and 1. **Simply use it instead of Math.random()**. | ||
|
||
*The index.js of this boilerplate quickly demonstrates how to use these*. | ||
|
||
## How do Generative Tokens work | ||
|
||
This is how Generative Tokens work on fxhash: | ||
* you upload your project to the platform (see next section) | ||
* you mint your project | ||
* when a collector will mint its unique token from your Generative Token, a random hash will be hard-coded in the **fxhash code snippet** | ||
* the token will now have its own `index.html` file, with a **static** hash, ensuring its immutability | ||
|
||
The [Guide to mint a Generative Token](https://fxhash.xyz/articles/guide-mint-generative-token) give in-depth details about this process. | ||
|
||
|
||
# Publish your token | ||
|
||
Once you are happy with the results, you can run the following command: | ||
|
||
```sh | ||
$ npm run build | ||
``` | ||
|
||
This will create a `dist-zipped/project.zip` file. | ||
|
||
Go to [https://fxhash.xyz/sandbox/](https://fxhash.xyz/sandbox/) and upload the `project.zip` file in there to see if it works properly. | ||
|
||
If your token does not work properly, you can iterate easily by updating your files, running `$ npm run build` again, and upload the zip file again. | ||
|
||
Finally, you can mint your token using the same `project.zip`file. | ||
|
||
|
||
# Rules to follow | ||
|
||
> Theses rules must be followed to ensure that your token will be future-proof, accepted by fxhash, and behave in the intended way | ||
* the zip file must be under 15 Mb | ||
* any path to a resource must be relative (./path/to/file.ext) | ||
* no external resources allowed, you must put all your resources in the `public/` folder (sub-folders are OK) | ||
* no network calls allowed (but calls to get resources from within your `public/` folder) | ||
* you must handle any viewport size (by implementing a response to the `resize` event of the `window`) | ||
* you **cannot use random number generation without a seed** (the same input hash must always yield the same output). The `fxrand` function does a very good job in that regard. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const path = require("path") | ||
const AdmZip = require("adm-zip") | ||
|
||
|
||
const defaultOptions = { | ||
outputPath: path.resolve(__dirname, "../dist-zipped/project.zip") | ||
} | ||
|
||
/** | ||
* The zipper plugin hooks to the end of compilation event, and it creates a ZIP file of | ||
* all the files within the ./dist folder into the ./dist-zipped folder to create a file | ||
* ready to be deployed on fxhash. | ||
* https://webpack.js.org/contribute/writing-a-plugin/ | ||
*/ | ||
class ZipperPlugin { | ||
constructor(options = {}) { | ||
this.options = { | ||
...defaultOptions, | ||
...options | ||
} | ||
} | ||
|
||
apply(compiler) { | ||
// Specify the event hook to attach to | ||
compiler.hooks.done.tapAsync( | ||
"ZipperPlugin", | ||
(stats, callback) => { | ||
const outputPath = stats.compilation.outputOptions.path | ||
const zip = new AdmZip() | ||
zip.addLocalFolder(outputPath) | ||
zip.toBuffer() | ||
zip.writeZip(this.options.outputPath) | ||
callback() | ||
} | ||
) | ||
} | ||
} | ||
|
||
module.exports = ZipperPlugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
const config = require("./webpack.config"); | ||
|
||
module.exports = { | ||
...config, | ||
mode: "development", | ||
devServer: { | ||
// disables the Hot Module Replacement feature because probably not ideal | ||
// in the context of generative art | ||
// https://webpack.js.org/concepts/hot-module-replacement/ | ||
hot: false, | ||
open: true, | ||
client: { | ||
overlay: { | ||
errors: true, | ||
warnings: false, | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const path = require("path"); | ||
const webpack = require("webpack"); | ||
const HtmlWebpackPlugin = require("html-webpack-plugin"); | ||
|
||
console.log("__dirname", __dirname); | ||
|
||
module.exports = { | ||
entry: "./src/index.js", | ||
output: { | ||
path: path.resolve(__dirname, "../dist"), | ||
filename: "bundle.js", | ||
clean: true, | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.css$/i, | ||
use: ["style-loader", "css-loader"], | ||
}, | ||
{ | ||
test: /\.(glsl|vert|frag)$/, | ||
use: ["raw-loader", "glslify-loader"], | ||
}, | ||
], | ||
}, | ||
plugins: [ | ||
new HtmlWebpackPlugin({ | ||
template: "./public/index.html", | ||
inject: "body", | ||
publicPath: "./", | ||
}), | ||
], | ||
resolve: { | ||
alias: { | ||
alfrid: path.resolve(__dirname, "../src/alfrid"), | ||
shaders: path.resolve(__dirname, "../src/shaders"), | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const CopyPlugin = require("copy-webpack-plugin") | ||
const config = require("./webpack.config") | ||
const ZipperPlugin = require("./ZipperPlugin") | ||
const path = require("path") | ||
|
||
module.exports = { | ||
...config, | ||
mode: "production", | ||
// add the zipper plugin to the list of plugins | ||
plugins: [ | ||
...config.plugins, | ||
new CopyPlugin({ | ||
patterns: [ | ||
{ | ||
from: "public", | ||
// prevents the index.html from being copied to the the public folder, as it's going to be | ||
// generated by webpack | ||
filter: async (filePath) => { | ||
return path.basename(filePath) !== "index.html" | ||
} | ||
} | ||
] | ||
}), | ||
new ZipperPlugin() | ||
] | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.