Support WebPack 5
parent
3aede0bc1a
commit
73f07f6bea
|
@ -2,4 +2,6 @@ dist
|
|||
node_modules
|
||||
|
||||
app/*.js
|
||||
app/*.js.map
|
||||
app/*.js.map
|
||||
|
||||
dist-plugin/
|
|
@ -14,4 +14,4 @@ ReactDOM.render(<>
|
|||
{classList.map(icon => {
|
||||
return <React.Fragment key={icon}><div className={"icon_em " + icon} /><br /></React.Fragment>;
|
||||
})}
|
||||
</>, container);
|
||||
</>, container);
|
|
@ -2,14 +2,13 @@
|
|||
* DO NOT MODIFY THIS FILE!
|
||||
*
|
||||
* This file has been auto generated by the svg-sprite generator.
|
||||
* Sprite source directory: D:\git\web\webpack-svg-sprite\demo\sprites
|
||||
* Sprite count: 21
|
||||
* Sprite source directory: D:\__on_g__git\web\webpack-svg-sprite\demo\sprites
|
||||
* Sprite count: 22
|
||||
*/
|
||||
declare module "svg-sprites/test" {
|
||||
export type TestIconClasses = "client-_player_commander_on" | "client-about" | "client-activate_microphone" | "client-add" | "client-add_foe" | "client-add_folder" | "client-add_friend" | "client-addon-collection" | "client-addon" | "client-apply" | "client-arrow_down" | "client-arrow_left" | "client-arrow_right" | "client-arrow_up" | "client-away" | "client-ban_client" | "client-ban_list" | "client-bookmark_add" | "client-bookmark_add_folder" | "client-bookmark_duplicate" | "client-w2g";
|
||||
export type TestIconClasses = "client-about" | "client-activate_microphone" | "client-add" | "client-add_foe" | "client-add_folder" | "client-add_friend" | "client-addon-collection" | "client-addon" | "client-apply" | "client-arrow_down" | "client-arrow_left" | "client-arrow_right" | "client-arrow_up" | "client-away" | "client-ban_client" | "client-ban_list" | "client-bookmark_add" | "client-bookmark_add_folder" | "client-bookmark_duplicate" | "client-channel_popin" | "client-player_off" | "client-w2g";
|
||||
|
||||
export enum TestIcons {
|
||||
PlayerCommanderOn = "client-_player_commander_on",
|
||||
About = "client-about",
|
||||
ActivateMicrophone = "client-activate_microphone",
|
||||
Add = "client-add",
|
||||
|
@ -29,6 +28,8 @@ declare module "svg-sprites/test" {
|
|||
BookmarkAdd = "client-bookmark_add",
|
||||
BookmarkAddFolder = "client-bookmark_add_folder",
|
||||
BookmarkDuplicate = "client-bookmark_duplicate",
|
||||
ChannelPopin = "client-channel_popin",
|
||||
PlayerOff = "client-player_off",
|
||||
W2g = "client-w2g",
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"name": "svg-sprite-demo",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/react": "^16.9.45",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"ts-loader": "^8.0.2",
|
||||
"typescript": "^3.9.7",
|
||||
"webpack": "^4.44.1",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs": "0.0.1-security",
|
||||
"fs-extra": "^9.0.1",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg id="client-channel_popin" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(.66666 0 0 .66666 0 .00016666)">
|
||||
<path d="m23.707.293c-.391-.391-1.023-.391-1.414 0l-4.97 4.97-2.043-2.043c-.214-.215-.537-.279-.817-.163s-.463.39-.463.693v5.5c0 .414.336.75.75.75h5.5c.303 0 .577-.183.693-.463s.052-.603-.163-.817l-2.043-2.043 4.97-4.97c.391-.391.391-1.023 0-1.414z" fill="#fff"/>
|
||||
</g>
|
||||
<g transform="matrix(.66666 0 0 .66666 0 .00016666)">
|
||||
<path d="m18 19v2c0 .55-.45 1-1 1h-14c-.55 0-1-.45-1-1v-13.95c-1.14.23-2 1.24-2 2.45v12c0 1.38 1.12 2.5 2.5 2.5h15c1.38 0 2.5-1.12 2.5-2.5v-2.5z" fill="#ccc"/>
|
||||
</g>
|
||||
<g transform="matrix(.66666 0 0 .66666 0 .00016666)">
|
||||
<path d="m22 6.25v.87l.19.19c.79.79 1.03 1.96.6 2.99-.18.43-.45.79-.79 1.06v2.64c0 .55-.45 1-1 1h-14c-.55 0-1-.45-1-1v-9h6v-1.25c0-1.12.67-2.11 1.7-2.54s2.21-.19 3 .6l.62.62 2.44-2.43h-13.26c-1.38 0-2.5 1.12-2.5 2.5v12c0 1.38 1.12 2.5 2.5 2.5h15c1.38 0 2.5-1.12 2.5-2.5v-10.26z" fill="#7289da"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -1,8 +1,8 @@
|
|||
import * as path from "path";
|
||||
import {Configuration} from "webpack";
|
||||
import {CleanWebpackPlugin} from "clean-webpack-plugin";
|
||||
import * as SpriteGenerator from "../plugin";
|
||||
import * as HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
import * as SpriteGenerator from "../plugin/";
|
||||
|
||||
export = {
|
||||
entry: path.join(__dirname, "app", "index.tsx"),
|
||||
|
@ -47,18 +47,23 @@ export = {
|
|||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
loader: [
|
||||
use: [
|
||||
"ts-loader"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
mode: process.env.NODE_ENV === "development" ? "development" : "production",
|
||||
|
||||
devServer: {
|
||||
contentBase: path.join(__dirname, 'dist'),
|
||||
compress: true,
|
||||
port: 9000,
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".tsx", ".css", ".js"]
|
||||
},
|
||||
output: {
|
||||
filename: "[name].[contenthash].js",
|
||||
path: path.resolve(__dirname, "dist")
|
||||
}
|
||||
} as Configuration;
|
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"name": "webpack-svg-sprite-generator",
|
||||
"version": "1.0.17",
|
||||
"version": "5.0.0",
|
||||
"description": "",
|
||||
"main": "plugin.js",
|
||||
"types": "ts/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
"build": "webpack",
|
||||
"build-demo": "webpack --config demo/webpack.config.js",
|
||||
"serve-demo": "webpack-dev-server --config demo/webpack.config.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "WolverinDEV",
|
||||
|
@ -18,21 +20,28 @@
|
|||
"type": "git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/tapable": "^1.0.6",
|
||||
"@types/webpack": "^4.41.21",
|
||||
"@webpack-cli/serve": "^1.3.0",
|
||||
"change-case": "^4.1.1",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^6.0.3",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"sha1": "^1.1.1",
|
||||
"ts-loader": "^8.0.2",
|
||||
"typescript": "^3.9.7",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"xml-parser": "^1.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"path": "^0.12.7",
|
||||
"webpack": "^4.44.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"potpack": "^1.0.1"
|
||||
"path": "^0.12.7",
|
||||
"potpack": "^1.0.1",
|
||||
"webpack": "^5.26.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import * as fs from "fs-extra";
|
||||
import * as path from "path";
|
||||
import * as XMLParser from "xml-parser";
|
||||
import { pascalCase } from "change-case";
|
||||
|
||||
let potpack = require("potpack");
|
||||
if(typeof potpack !== "function" && potpack.default)
|
||||
potpack = potpack.default;
|
||||
import XMLParser from "xml-parser";
|
||||
import potpack from "potpack";
|
||||
|
||||
function generateAttributes(attributes: XMLParser.Attributes) {
|
||||
const keys = Object.keys(attributes);
|
||||
|
@ -50,7 +48,7 @@ export async function generateSpriteSvg(sprite: GeneratedSprite) {
|
|||
let result = "";
|
||||
result += `<?xml version="1.0" encoding="utf-8"?>\n`;
|
||||
result += `<!-- ${sprite.entries.length} icons packed -->\n`;
|
||||
result += `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${sprite.width}" height="${sprite.height}" viewBox="0 0 ${sprite.width} ${sprite.height}">\n`;
|
||||
result += `<svg xmlns="http://www.w3.org/2000/svg" width="${sprite.width}" height="${sprite.height}" viewBox="0 0 ${sprite.width} ${sprite.height}">\n`;
|
||||
|
||||
for(const file of sprite.entries) {
|
||||
const root = file.data.root;
|
||||
|
@ -252,13 +250,13 @@ export async function generateSpriteJs(options: SpriteDtsOptions, sprite: Genera
|
|||
lines.push(`let ClassList = [${sprite.entries.map(e => `"${cssClassPrefix}${e.name}", `)}];`);
|
||||
|
||||
lines.push(``);
|
||||
lines.push(`Object.defineProperty(exports, "__esModule", { value: true });`);
|
||||
lines.push(`exports.${options.enumName} = Object.freeze(EnumClassList);`);
|
||||
lines.push(`exports.spriteUrl = SpriteUrl;`);
|
||||
lines.push(`exports.classList = Object.freeze(ClassList);`);
|
||||
lines.push(`exports.spriteEntries = Object.freeze(SpriteEntries);`);
|
||||
lines.push(`exports.spriteWidth = ${sprite.width};`);
|
||||
lines.push(`exports.spriteHeight = ${sprite.height};`);
|
||||
lines.push(`Object.defineProperty(module.exports, "__esModule", { value: true });`);
|
||||
lines.push(`module.exports.${options.enumName} = Object.freeze(EnumClassList);`);
|
||||
lines.push(`module.exports.spriteUrl = SpriteUrl;`);
|
||||
lines.push(`module.exports.classList = Object.freeze(ClassList);`);
|
||||
lines.push(`module.exports.spriteEntries = Object.freeze(SpriteEntries);`);
|
||||
lines.push(`module.exports.spriteWidth = ${sprite.width};`);
|
||||
lines.push(`module.exports.spriteHeight = ${sprite.height};`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
|
@ -291,7 +289,7 @@ export async function generateSprite(files: string[]) : Promise<GeneratedSprite>
|
|||
}
|
||||
|
||||
const rootAttributes = svg.data.root.attributes;
|
||||
const [ xOff, yOff, width, height ] = rootAttributes["viewBox"].split(" ").map(parseFloat);
|
||||
const [ /* xOff */, /* yOff */, width, height ] = rootAttributes["viewBox"].split(" ").map(parseFloat);
|
||||
|
||||
if(isNaN(width) || isNaN(height)) {
|
||||
console.warn("Skipping SVG %s because of invalid bounds (Parsed: %d x %d, Values: %o).", file, width, height, rootAttributes["viewBox"].split(" "));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import * as webpack from "webpack";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs-extra";
|
||||
import * as sha1 from "sha1";
|
||||
import sha1 from "sha1";
|
||||
|
||||
import {
|
||||
GeneratedSprite,
|
||||
|
@ -12,6 +11,12 @@ import {
|
|||
SpriteDtsOptions
|
||||
} from "./generator";
|
||||
|
||||
const Module = require("webpack/lib/Module");
|
||||
const RuntimeGlobals = require("webpack/lib/RuntimeGlobals");
|
||||
const { RawSource } = require("webpack-sources");
|
||||
|
||||
import {Compiler} from "webpack";
|
||||
|
||||
export interface Options {
|
||||
modulePrefix?: string, /* defaults to svg-sprites/ */
|
||||
dtsOutputFolder: string,
|
||||
|
@ -20,8 +25,6 @@ export interface Options {
|
|||
}
|
||||
}
|
||||
|
||||
const Module = require("webpack/lib/Module");
|
||||
const { RawSource } = require("webpack-sources");
|
||||
|
||||
interface SvgSpriteConfiguration {
|
||||
folder: string;
|
||||
|
@ -31,34 +34,47 @@ interface SvgSpriteConfiguration {
|
|||
cssOptions: SpriteCssOptions[];
|
||||
}
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
const RUNTIME_REQUIREMENTS = new Set([
|
||||
RuntimeGlobals.module
|
||||
]);
|
||||
|
||||
class SvgSpriteModule extends Module {
|
||||
private readonly pluginConfig: Options;
|
||||
private readonly configName: string;
|
||||
private readonly config: SvgSpriteConfiguration;
|
||||
|
||||
private sprite: GeneratedSprite;
|
||||
private spriteSvg: string;
|
||||
private spriteCss: string;
|
||||
private spriteJs: string;
|
||||
|
||||
private spriteAssetName: string;
|
||||
private spriteAssetUrl: string;
|
||||
|
||||
constructor(context: string, pluginConfig: Options, configName: string, config: SvgSpriteConfiguration) {
|
||||
super("javascript/dynamic", context);
|
||||
super("javascript/dynamic", null);
|
||||
this.pluginConfig = pluginConfig;
|
||||
this.configName = configName;
|
||||
this.config = config;
|
||||
this.buildInfo = {};
|
||||
this.clearDependenciesAndBlocks();
|
||||
}
|
||||
|
||||
getSourceTypes() {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
identifier() {
|
||||
return "svg-sprite/" + this.configName;
|
||||
}
|
||||
|
||||
readableIdentifier() {
|
||||
return `SVG sprite ` + this.configName;
|
||||
}
|
||||
|
||||
readableIdentifier(requestShortener) {
|
||||
return `SVG sprite ` + this.configName;
|
||||
}
|
||||
|
||||
needRebuild() {
|
||||
return false;
|
||||
needBuild(context, callback) {
|
||||
callback(null, !this.buildMeta);
|
||||
}
|
||||
|
||||
build(options, compilation, resolver, fs_, callback) {
|
||||
|
@ -71,7 +87,7 @@ class SvgSpriteModule extends Module {
|
|||
};
|
||||
this.buildInfo = {
|
||||
cacheable: true,
|
||||
assets: {}
|
||||
assets: {},
|
||||
};
|
||||
|
||||
if(this.spriteAssetName) {
|
||||
|
@ -84,7 +100,7 @@ class SvgSpriteModule extends Module {
|
|||
|
||||
this.spriteSvg = await generateSpriteSvg(this.sprite);
|
||||
this.spriteAssetName = "sprite-" + sha1(this.spriteSvg).substr(-20) + ".svg";
|
||||
this.spriteAssetUrl = (compilation.options.output.publicPath || "") + this.spriteAssetName;
|
||||
this.spriteAssetUrl = this.spriteAssetName;
|
||||
|
||||
this.buildInfo.assets[this.spriteAssetName] = new RawSource(this.spriteSvg);
|
||||
|
||||
|
@ -105,7 +121,9 @@ class SvgSpriteModule extends Module {
|
|||
});
|
||||
}
|
||||
|
||||
source() {
|
||||
codeGeneration(context) {
|
||||
const sources = new Map();
|
||||
|
||||
const encodedCss = this.spriteCss
|
||||
.replace(/%/g, "%25")
|
||||
.replace(/"/g, "%22")
|
||||
|
@ -119,7 +137,9 @@ class SvgSpriteModule extends Module {
|
|||
lines.push(``);
|
||||
lines.push(`/* initialize typescript objects */`);
|
||||
lines.push(...this.spriteJs.split("\n"));
|
||||
return new RawSource(lines.join("\n"));
|
||||
|
||||
sources.set("javascript", new RawSource(lines.join("\n")));
|
||||
return { sources: sources, runtimeRequirements: RUNTIME_REQUIREMENTS };
|
||||
}
|
||||
|
||||
size() {
|
||||
|
@ -133,8 +153,11 @@ class SvgSpriteModule extends Module {
|
|||
hash.update(this.spriteSvg || "none");
|
||||
super.updateHash(hash, chunkGraph);
|
||||
}
|
||||
|
||||
addReason(_requestModule, _dependency) { }
|
||||
}
|
||||
|
||||
|
||||
export class SpriteGenerator {
|
||||
readonly options: Options;
|
||||
constructor(options: Options) {
|
||||
|
@ -143,20 +166,19 @@ export class SpriteGenerator {
|
|||
this.options.modulePrefix = this.options.modulePrefix || "svg-sprites/";
|
||||
}
|
||||
|
||||
apply(compiler: webpack.Compiler) {
|
||||
compiler.hooks.thisCompilation.tap("SpriteGenerator", (compilation, { normalModuleFactory }) => {
|
||||
normalModuleFactory.hooks.factory.tap("SpriteGenerator", factory => (data, callback) => {
|
||||
if(data.request.startsWith(this.options.modulePrefix)) {
|
||||
const configName = data.request.substr(this.options.modulePrefix.length);
|
||||
if(this.options.configurations[configName] === undefined) {
|
||||
callback("Missing SVG configuration " + configName);
|
||||
return;
|
||||
}
|
||||
callback(null, new SvgSpriteModule(data.request, this.options, configName, this.options.configurations[configName]));
|
||||
apply(compiler: Compiler) {
|
||||
compiler.hooks.normalModuleFactory.tap("SpriteGenerator", normalModuleFactory => {
|
||||
normalModuleFactory.hooks.resolve.tap("SpriteGenerator", resolveData => {
|
||||
if(!resolveData.request.startsWith(this.options.modulePrefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
factory(data, callback);
|
||||
const configName = resolveData.request.substr(this.options.modulePrefix.length);
|
||||
if(!this.options.configurations[configName]) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new SvgSpriteModule(resolveData.request, this.options, configName, this.options.configurations[configName]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
"sourceMap": false,
|
||||
"declarationDir": "dist/ts",
|
||||
"declarationMap": false,
|
||||
"declaration": true
|
||||
"declaration": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": [
|
||||
"plugin"
|
||||
|
|
|
@ -51,7 +51,7 @@ export = {
|
|||
|
||||
target: "node",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
path: process.env.OUTPUT_PATH || path.resolve(__dirname, "dist"),
|
||||
filename: "plugin.js",
|
||||
|
||||
libraryTarget: "umd",
|
||||
|
|
Loading…
Reference in New Issue