Skip to content

Commit

Permalink
Merge pull request #1 from DauMoe/dev
Browse files Browse the repository at this point in the history
Merge new code base into master
  • Loading branch information
DauMoe authored Mar 30, 2024
2 parents 635f26f + 3b16405 commit 909a011
Show file tree
Hide file tree
Showing 14 changed files with 4,319 additions and 177 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
.vscode
sprite
79 changes: 13 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,11 @@
# Sprite PNG plugin
Webpack plugin uses [Spritesmith](https://github.com/twolfson/spritesmith) to helping create PNG sprite image and coordinate mapping file (`manifest.json`)
Webpack plugin helps to create PNG sprite image and coordinate mapping file (`manifest.json`)
## Usage:
- Make sure [ImageMagick](https://imagemagick.org/) is installed on your device and add it to PATH. Because `Spritesmith` works on top of it
- Make sure your assets is actual `png` image. You can use online converter tool (JPG -> PNG, JPEG -> PNG, SVG -> PNG, ...). And DO NOT change file extension directly (I do it and got error `Invalid signature`)
- The manifest path should be relative path from current webpack config container directory
- Manifest file will be generated automatically. You must remember exactly where it is. Help you a lot to import it into code base

## Options:
| Option | Type | Required | Default | Description |
|----------------------|-------------------------|----------|---------------------|--------------------------------------------------------------|
| **outputPath** | `string` | No | Webpack output path | Your output build path. Default will get from webpack output |
| **includes** | `RegExp` | `Array` | No | `undefined` | Reg to filter the images for sprite |
| **manifestFileName** | `string` | No | `manifest.json` | Coordinate file name (path name is accepted) |

## Manifest content format
```yaml
{
"width": <number>,
"height": <number>,
"frames": {
[image_1_name]: {
"width": <number>,
"height": <number>,
"x": <number>
"y": <number>
},
[image_2_name]: {
...so_on
},
...
}
}
```
- **width**: sprite sheet width
- **height**: sprite sheet height
- **frames**: contain each images coordinate (x, y, w, h)

## Example
**Folder structure**
```
├── code_base/
│ └── src/
│ ├── index.js
│ └── assets/
│ ├── image_1.png
│ ├── image_2.png
│ └── ...
└── webpack.config.js
```

**index.js**
Suppose you want a manifest.json file in `src/asset/manifest.json`. You can import it into any place without creating it, plugin will handle that
```js
import React from "react";
...
import * as mappingData from "./assets/manifest.json"; // no need to create this file. Just remember the path
import { getIcon } from ...; // outputDir + getIcon.js

return (
<YourComponent>
Expand All @@ -64,33 +16,28 @@ return (
```js
const SpritePNG = require("sprite-png-plugin");
...
const spriter = new SpritePNG({
manifestFileName: "./src/assets/manifest.json" // Path to generate manifest file
});

...
module.exports = {
...,
module: {
...,
rules: [
...,
{
test: /\.png$/,
type: 'asset/resource'
},
...
],
plugins: [
...,
spriter,
new SpritePNG({
...options
})
...
],
...
}
}
```

## Options:

## Inspiration by:
- [image-sprite-webpack-plugin](https://github.com/naver/image-sprite-webpack-plugin)
- [webpack-virtual-modules](https://github.com/sysgears/webpack-virtual-modules)
| Option | Type | Required | Default | Description |
| ------------- | ------------------------------------------------------------- | -------- | ----------- | -------------------------------------- |
| **outputDir** | `String` | No | ./ | Output directory for sprite sheet data |
| **excludes** | `RegExp` &#124; `Array` | No | `undefined` | Reg to filter the images for sprite |
| **entry** | `String` &#124; `RegExp` &#124; `Array<String`&#124;`RegExp>` | No | [] | images entry |
29 changes: 29 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "sprite_png_example",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"serve": "webpack serve --config webpack.config.js",
"build": "webpack --config webpack.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "https://github.com/DauMoe",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.0.0",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^9.1.3",
"css-loader": "^3.4.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.2",
"react": "^17.0.2",
"react-dom": "17.0.1",
"react-refresh": "^0.14.0",
"style-loader": "^1.1.2",
"webpack": "^5.90.3",
"webpack-cli": "^4.3.0",
"webpack-dev-server": "^4.15.1"
}
}
Binary file added example/src/another/test_3_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/src/another/test_gl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions example/src/components/com_1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

const CompOne = () => {
return (
<div>Iam component 1</div>
)
}

export default CompOne;
24 changes: 24 additions & 0 deletions example/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import ReactDOM from "react-dom";
import { getIcon } from "./sprite/getIcon";

// import ABC from "./another/test_1.png";
// import AccountRemove from "./another/test_2.png";
// import Account from "./another/test_3.png";
// import ABC_1 from "./media/test_4.png";
// import transparent from "./media/transparent.png";

const AppElement = () => {
const icon1 = getIcon(".png");
return (
<div>
<p>Tes_1</p>
<img src={icon1.url} width={icon1.width} height={icon1.height} />
</div>
);
};
const root = document.querySelector("body");
ReactDOM.render(
<AppElement />,
root
);
Binary file added example/src/media/account-green_.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions example/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SpritePNG = require("../index");

const subStylePaths = [];

const setupCacheGroups = () => {
return subStylePaths.reduce((acc, cur) => {
acc[cur.name] = {
name: cur.name,
test: (m, c, entry = cur.name) => {
return m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry;
},
chunks: 'all',
enforce: true
};
return acc;
}, {});
};

const sourcePath = path.resolve(__dirname, 'src');
const isProd = false;

module.exports = {
mode: isProd ? "production" : "development",
entry: {
bundle: ['@babel/polyfill', path.resolve(sourcePath, './index.js')],
},
output: {
path: path.join(__dirname, "dist"),
publicPath: '/',
filename: '[name].js',
assetModuleFilename: `./assets/[name][ext]`,
},
optimization: {
splitChunks: {
cacheGroups: setupCacheGroups()
},
},
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: "defaults"
}
]
]
}
},
{
test: /\.png$/,
type: 'asset/resource',
}
]
},
stats: {
errors: true,
errorStack: true,
errorDetails: true, // --display-error-details
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "index.html"
}),
new SpritePNG({
entry: [ 'src/media/**/*.png', 'src/another/**/*'],
excludes: /.*\/src\/another\/test_gl\.png$/,
outputDir: "./src/sprite"
})
],
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
},
};
Loading

0 comments on commit 909a011

Please sign in to comment.