svger-cli 2.0.7 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +259 -9
- package/README.md +383 -13
- package/dist/index.d.ts +30 -0
- package/dist/index.js +33 -0
- package/dist/integrations/babel.d.ts +58 -0
- package/dist/integrations/babel.js +221 -0
- package/dist/integrations/jest-preset.d.ts +44 -0
- package/dist/integrations/jest-preset.js +169 -0
- package/dist/integrations/nextjs.d.ts +56 -0
- package/dist/integrations/nextjs.js +140 -0
- package/dist/integrations/rollup.d.ts +29 -0
- package/dist/integrations/rollup.js +197 -0
- package/dist/integrations/vite.d.ts +29 -0
- package/dist/integrations/vite.js +221 -0
- package/dist/integrations/webpack.d.ts +84 -0
- package/dist/integrations/webpack.js +273 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -1
- package/dist/types/integrations.d.ts +255 -0
- package/dist/types/integrations.js +4 -0
- package/docs/INTEGRATION-IMPLEMENTATION-SUMMARY.md +448 -0
- package/docs/INTEGRATIONS.md +543 -0
- package/examples/babel.config.example.js +182 -0
- package/examples/jest.config.example.js +158 -0
- package/examples/next.config.example.js +133 -0
- package/examples/rollup.config.example.js +129 -0
- package/examples/vite.config.example.js +98 -0
- package/examples/webpack.config.example.js +88 -0
- package/package.json +75 -5
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Babel Plugin for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Transforms SVG imports into framework components during Babel transpilation.
|
|
5
|
+
* Works with any Babel-based build process including standalone Babel, Create React App,
|
|
6
|
+
* and other tools that use Babel under the hood.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```js
|
|
10
|
+
* // babel.config.js
|
|
11
|
+
* const { svgerBabelPlugin } = require('svger-cli/babel');
|
|
12
|
+
*
|
|
13
|
+
* module.exports = {
|
|
14
|
+
* plugins: [
|
|
15
|
+
* [svgerBabelPlugin, {
|
|
16
|
+
* source: './src/icons',
|
|
17
|
+
* output: './src/components/icons',
|
|
18
|
+
* framework: 'react',
|
|
19
|
+
* typescript: true
|
|
20
|
+
* }]
|
|
21
|
+
* ]
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```js
|
|
27
|
+
* // Direct SVG import transformation
|
|
28
|
+
* import Icon from './icon.svg';
|
|
29
|
+
* // Transforms to:
|
|
30
|
+
* import Icon from './components/icons/Icon';
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import path from 'path';
|
|
34
|
+
import { FileSystem } from '../utils/native.js';
|
|
35
|
+
import { svgProcessor } from '../processors/svg-processor.js';
|
|
36
|
+
import { configService } from '../services/config.js';
|
|
37
|
+
import { logger } from '../core/logger.js';
|
|
38
|
+
const PLUGIN_NAME = 'svger-babel-plugin';
|
|
39
|
+
/**
|
|
40
|
+
* Process all SVG files in the source directory
|
|
41
|
+
*/
|
|
42
|
+
async function processAllSVGs(options, processedFiles) {
|
|
43
|
+
const sourcePath = path.resolve(options.source);
|
|
44
|
+
const outputPath = path.resolve(options.output);
|
|
45
|
+
if (!(await FileSystem.exists(sourcePath))) {
|
|
46
|
+
logger.warn(`Source directory not found: ${sourcePath}`);
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const files = await FileSystem.readDir(sourcePath);
|
|
50
|
+
const svgFiles = files.filter(file => file.endsWith('.svg'));
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const file of svgFiles) {
|
|
53
|
+
const filePath = path.join(sourcePath, file);
|
|
54
|
+
if (processedFiles.has(filePath))
|
|
55
|
+
continue;
|
|
56
|
+
try {
|
|
57
|
+
const svgContent = await FileSystem.readFile(filePath, 'utf-8');
|
|
58
|
+
const componentName = svgProcessor.generateComponentName(file, 'pascal');
|
|
59
|
+
const config = configService.readConfig();
|
|
60
|
+
const component = await svgProcessor.generateComponent(componentName, svgContent, {
|
|
61
|
+
framework: options.framework,
|
|
62
|
+
typescript: options.typescript,
|
|
63
|
+
defaultWidth: config.defaultWidth,
|
|
64
|
+
defaultHeight: config.defaultHeight,
|
|
65
|
+
defaultFill: config.defaultFill,
|
|
66
|
+
styleRules: config.styleRules || {},
|
|
67
|
+
});
|
|
68
|
+
const ext = options.typescript ? 'tsx' : 'jsx';
|
|
69
|
+
const outputFile = path.join(outputPath, `${componentName}.${ext}`);
|
|
70
|
+
await FileSystem.ensureDir(path.dirname(outputFile));
|
|
71
|
+
await FileSystem.writeFile(outputFile, component);
|
|
72
|
+
processedFiles.add(filePath);
|
|
73
|
+
results.push({
|
|
74
|
+
success: true,
|
|
75
|
+
outputPath: outputFile,
|
|
76
|
+
componentName,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
logger.error(`Failed to process ${file}:`, error);
|
|
81
|
+
results.push({
|
|
82
|
+
success: false,
|
|
83
|
+
error: error,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Generate index file if enabled
|
|
88
|
+
if (options.generateIndex && results.length > 0) {
|
|
89
|
+
try {
|
|
90
|
+
await generateIndexFile(outputPath, results, options);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
logger.error('Failed to generate index file:', error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate index file with all exports
|
|
100
|
+
*/
|
|
101
|
+
async function generateIndexFile(outputDir, results, options) {
|
|
102
|
+
const extension = options.typescript ? 'ts' : 'js';
|
|
103
|
+
const exports = results
|
|
104
|
+
.filter(r => r.componentName)
|
|
105
|
+
.map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
|
|
106
|
+
.join('\n');
|
|
107
|
+
const indexPath = path.join(outputDir, `index.${extension}`);
|
|
108
|
+
await FileSystem.writeFile(indexPath, exports, 'utf-8');
|
|
109
|
+
logger.debug(`Generated index file: ${indexPath}`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Transform SVG import path to component path
|
|
113
|
+
*/
|
|
114
|
+
function transformSVGImport(sourcePath, options) {
|
|
115
|
+
if (!sourcePath.endsWith('.svg'))
|
|
116
|
+
return null;
|
|
117
|
+
const absoluteOutput = path.resolve(options.output);
|
|
118
|
+
// Extract filename without extension
|
|
119
|
+
const fileName = path.basename(sourcePath, '.svg');
|
|
120
|
+
const componentName = svgProcessor.generateComponentName(fileName, 'pascal');
|
|
121
|
+
// Calculate relative path from output to component
|
|
122
|
+
const ext = options.typescript ? 'tsx' : 'jsx';
|
|
123
|
+
return path.join(absoluteOutput, `${componentName}.${ext}`);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Babel Plugin for SVGER-CLI
|
|
127
|
+
*
|
|
128
|
+
* This plugin processes SVG files and transforms SVG imports to component imports.
|
|
129
|
+
* It can run in two modes:
|
|
130
|
+
* - Pre-build: Process all SVGs before Babel transformation
|
|
131
|
+
* - On-demand: Transform SVG imports as they're encountered
|
|
132
|
+
*/
|
|
133
|
+
export function svgerBabelPlugin(api, options = {}) {
|
|
134
|
+
const config = configService.readConfig();
|
|
135
|
+
const pluginOptions = {
|
|
136
|
+
source: options.source || config.source || './src/icons',
|
|
137
|
+
output: options.output || config.output || './src/components/icons',
|
|
138
|
+
framework: options.framework || config.framework || 'react',
|
|
139
|
+
typescript: options.typescript !== undefined ? options.typescript : config.typescript,
|
|
140
|
+
config: options.config || {},
|
|
141
|
+
include: options.include || ['**/*.svg'],
|
|
142
|
+
exclude: options.exclude || ['node_modules/**'],
|
|
143
|
+
transformImports: options.transformImports !== undefined ? options.transformImports : true,
|
|
144
|
+
processOnInit: options.processOnInit !== undefined ? options.processOnInit : true,
|
|
145
|
+
generateIndex: options.generateIndex !== undefined ? options.generateIndex : true,
|
|
146
|
+
};
|
|
147
|
+
const processedFiles = new Set();
|
|
148
|
+
let initialized = false;
|
|
149
|
+
return {
|
|
150
|
+
name: PLUGIN_NAME,
|
|
151
|
+
// Babel visitor pattern
|
|
152
|
+
visitor: {
|
|
153
|
+
// Process before any transformations if enabled
|
|
154
|
+
Program: {
|
|
155
|
+
enter: async () => {
|
|
156
|
+
if (!initialized && pluginOptions.processOnInit) {
|
|
157
|
+
initialized = true;
|
|
158
|
+
logger.info('SVGER Babel Plugin: Processing SVG files...');
|
|
159
|
+
const results = await processAllSVGs(pluginOptions, processedFiles);
|
|
160
|
+
const successCount = results.filter(r => r.success).length;
|
|
161
|
+
if (successCount > 0) {
|
|
162
|
+
logger.info(`SVGER Babel Plugin: Processed ${successCount} SVG files`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
// Transform import declarations
|
|
168
|
+
ImportDeclaration(nodePath) {
|
|
169
|
+
if (!pluginOptions.transformImports)
|
|
170
|
+
return;
|
|
171
|
+
const source = nodePath.node.source.value;
|
|
172
|
+
if (typeof source === 'string' && source.endsWith('.svg')) {
|
|
173
|
+
const newPath = transformSVGImport(source, pluginOptions);
|
|
174
|
+
if (newPath) {
|
|
175
|
+
// Replace the import source
|
|
176
|
+
nodePath.node.source.value = newPath.replace(/\.(tsx|jsx)$/, '');
|
|
177
|
+
logger.debug(`SVGER Babel Plugin: Transformed ${source} -> ${newPath}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
// Handle dynamic imports
|
|
182
|
+
CallExpression(nodePath) {
|
|
183
|
+
if (!pluginOptions.transformImports)
|
|
184
|
+
return;
|
|
185
|
+
const callee = nodePath.node.callee;
|
|
186
|
+
// Check for import() calls
|
|
187
|
+
if (callee.type === 'Import') {
|
|
188
|
+
const args = nodePath.node.arguments;
|
|
189
|
+
if (args.length > 0 && args[0].type === 'StringLiteral') {
|
|
190
|
+
const source = args[0].value;
|
|
191
|
+
if (source.endsWith('.svg')) {
|
|
192
|
+
const newPath = transformSVGImport(source, pluginOptions);
|
|
193
|
+
if (newPath) {
|
|
194
|
+
args[0].value = newPath.replace(/\.(tsx|jsx)$/, '');
|
|
195
|
+
logger.debug(`SVGER Babel Plugin: Transformed dynamic import ${source} -> ${newPath}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Create a Babel plugin instance with preset options
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```js
|
|
209
|
+
* const plugin = createBabelPlugin({
|
|
210
|
+
* source: './icons',
|
|
211
|
+
* framework: 'react'
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export function createBabelPlugin(options = {}) {
|
|
216
|
+
return (api) => svgerBabelPlugin(api, options);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Default export for convenient usage
|
|
220
|
+
*/
|
|
221
|
+
export default svgerBabelPlugin;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Jest Preset for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides Jest transformers and configuration for testing SVG components
|
|
5
|
+
* with full framework support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```js
|
|
9
|
+
* // jest.config.js
|
|
10
|
+
* module.exports = {
|
|
11
|
+
* preset: 'svger-cli/jest',
|
|
12
|
+
* // or manually configure:
|
|
13
|
+
* transform: {
|
|
14
|
+
* '\\.svg$': 'svger-cli/jest-transformer'
|
|
15
|
+
* }
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import type { JestPresetOptions } from '../types/integrations.js';
|
|
20
|
+
/**
|
|
21
|
+
* Jest transformer for SVG files
|
|
22
|
+
*/
|
|
23
|
+
export declare const svgerJestTransformer: {
|
|
24
|
+
process(sourceText: string, sourcePath: string, options: any): {
|
|
25
|
+
code: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Jest preset configuration
|
|
30
|
+
*/
|
|
31
|
+
export declare const jestPreset: {
|
|
32
|
+
transform: {
|
|
33
|
+
'\\.svg$': {}[];
|
|
34
|
+
};
|
|
35
|
+
moduleNameMapper: {
|
|
36
|
+
'\\.svg$': string;
|
|
37
|
+
};
|
|
38
|
+
transformIgnorePatterns: string[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Create custom Jest transformer with options
|
|
42
|
+
*/
|
|
43
|
+
export declare function createJestTransformer(options?: JestPresetOptions): typeof svgerJestTransformer;
|
|
44
|
+
export default svgerJestTransformer;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Jest Preset for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides Jest transformers and configuration for testing SVG components
|
|
5
|
+
* with full framework support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```js
|
|
9
|
+
* // jest.config.js
|
|
10
|
+
* module.exports = {
|
|
11
|
+
* preset: 'svger-cli/jest',
|
|
12
|
+
* // or manually configure:
|
|
13
|
+
* transform: {
|
|
14
|
+
* '\\.svg$': 'svger-cli/jest-transformer'
|
|
15
|
+
* }
|
|
16
|
+
* };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import { svgProcessor } from '../processors/svg-processor.js';
|
|
20
|
+
import { configService } from '../services/config.js';
|
|
21
|
+
/**
|
|
22
|
+
* Jest transformer for SVG files
|
|
23
|
+
*/
|
|
24
|
+
export const svgerJestTransformer = {
|
|
25
|
+
process(sourceText, sourcePath, options) {
|
|
26
|
+
const config = configService.readConfig();
|
|
27
|
+
const transformOptions = options?.transformerConfig?.svger || {};
|
|
28
|
+
// Check if we should mock instead of transform
|
|
29
|
+
if (transformOptions.mock) {
|
|
30
|
+
const componentName = svgProcessor.generateComponentName(sourcePath, 'pascal');
|
|
31
|
+
return {
|
|
32
|
+
code: `
|
|
33
|
+
const React = require('react');
|
|
34
|
+
const ${componentName} = (props) => React.createElement('svg', props);
|
|
35
|
+
module.exports = ${componentName};
|
|
36
|
+
module.exports.default = ${componentName};
|
|
37
|
+
`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Transform SVG to component
|
|
41
|
+
const framework = transformOptions.framework || config.framework || 'react';
|
|
42
|
+
const typescript = transformOptions.typescript !== undefined
|
|
43
|
+
? transformOptions.typescript
|
|
44
|
+
: config.typescript;
|
|
45
|
+
const componentName = svgProcessor.generateComponentName(sourcePath, 'pascal');
|
|
46
|
+
try {
|
|
47
|
+
// Generate component synchronously for Jest
|
|
48
|
+
const component = generateComponentSync(componentName, sourceText, {
|
|
49
|
+
framework,
|
|
50
|
+
typescript,
|
|
51
|
+
defaultWidth: config.defaultWidth,
|
|
52
|
+
defaultHeight: config.defaultHeight,
|
|
53
|
+
defaultFill: config.defaultFill,
|
|
54
|
+
styleRules: config.styleRules || {},
|
|
55
|
+
});
|
|
56
|
+
// Convert to CommonJS for Jest
|
|
57
|
+
const commonJsCode = convertToCommonJS(component, componentName);
|
|
58
|
+
return {
|
|
59
|
+
code: commonJsCode,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
// Return a simple mock on error
|
|
64
|
+
return {
|
|
65
|
+
code: `
|
|
66
|
+
const React = require('react');
|
|
67
|
+
const ${componentName} = (props) => React.createElement('svg', props);
|
|
68
|
+
module.exports = ${componentName};
|
|
69
|
+
module.exports.default = ${componentName};
|
|
70
|
+
`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Generate component synchronously (for Jest compatibility)
|
|
77
|
+
*/
|
|
78
|
+
function generateComponentSync(componentName, svgContent, options) {
|
|
79
|
+
// Clean SVG content
|
|
80
|
+
const cleanedContent = svgProcessor.cleanSVGContent(svgContent);
|
|
81
|
+
// For Jest, we'll generate a simple React component
|
|
82
|
+
const viewBox = svgProcessor.extractViewBox(svgContent);
|
|
83
|
+
const template = `
|
|
84
|
+
import React from 'react';
|
|
85
|
+
|
|
86
|
+
interface ${componentName}Props {
|
|
87
|
+
width?: number | string;
|
|
88
|
+
height?: number | string;
|
|
89
|
+
fill?: string;
|
|
90
|
+
className?: string;
|
|
91
|
+
style?: React.CSSProperties;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const ${componentName}: React.FC<${componentName}Props> = ({
|
|
95
|
+
width = ${options.defaultWidth || 24},
|
|
96
|
+
height = ${options.defaultHeight || 24},
|
|
97
|
+
fill = '${options.defaultFill || 'currentColor'}',
|
|
98
|
+
className,
|
|
99
|
+
style,
|
|
100
|
+
...props
|
|
101
|
+
}) => (
|
|
102
|
+
<svg
|
|
103
|
+
width={width}
|
|
104
|
+
height={height}
|
|
105
|
+
viewBox="${viewBox || '0 0 24 24'}"
|
|
106
|
+
fill={fill}
|
|
107
|
+
className={className}
|
|
108
|
+
style={style}
|
|
109
|
+
{...props}
|
|
110
|
+
>
|
|
111
|
+
${cleanedContent}
|
|
112
|
+
</svg>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export default ${componentName};
|
|
116
|
+
`;
|
|
117
|
+
return template.trim();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Convert ES modules to CommonJS for Jest
|
|
121
|
+
*/
|
|
122
|
+
function convertToCommonJS(code, componentName) {
|
|
123
|
+
// Simple conversion for Jest compatibility
|
|
124
|
+
let commonJsCode = code
|
|
125
|
+
.replace(/import\s+React\s+from\s+['"]react['"]/g, "const React = require('react')")
|
|
126
|
+
.replace(/export\s+default\s+/g, 'module.exports = ')
|
|
127
|
+
.replace(/export\s+{([^}]+)}/g, (match, exports) => {
|
|
128
|
+
const exportList = exports.split(',').map((e) => e.trim());
|
|
129
|
+
return exportList
|
|
130
|
+
.map((exp) => `module.exports.${exp} = ${exp}`)
|
|
131
|
+
.join(';');
|
|
132
|
+
});
|
|
133
|
+
// Ensure default export
|
|
134
|
+
if (!commonJsCode.includes('module.exports')) {
|
|
135
|
+
commonJsCode += `\nmodule.exports = ${componentName};`;
|
|
136
|
+
}
|
|
137
|
+
// Also add named export
|
|
138
|
+
commonJsCode += `\nmodule.exports.default = module.exports;`;
|
|
139
|
+
return commonJsCode;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Jest preset configuration
|
|
143
|
+
*/
|
|
144
|
+
export const jestPreset = {
|
|
145
|
+
transform: {
|
|
146
|
+
'\\.svg$': ['svger-cli/jest-transformer', {}],
|
|
147
|
+
},
|
|
148
|
+
moduleNameMapper: {
|
|
149
|
+
'\\.svg$': 'svger-cli/jest-transformer',
|
|
150
|
+
},
|
|
151
|
+
transformIgnorePatterns: ['node_modules/(?!(svger-cli)/)'],
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Create custom Jest transformer with options
|
|
155
|
+
*/
|
|
156
|
+
export function createJestTransformer(options = {}) {
|
|
157
|
+
return {
|
|
158
|
+
process(sourceText, sourcePath, jestOptions) {
|
|
159
|
+
return svgerJestTransformer.process(sourceText, sourcePath, {
|
|
160
|
+
...jestOptions,
|
|
161
|
+
transformerConfig: {
|
|
162
|
+
svger: options,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// Default exports
|
|
169
|
+
export default svgerJestTransformer;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Next.js Plugin for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Automatically converts SVG files to framework components in Next.js applications
|
|
5
|
+
* with full SSR support, HMR, and webpack integration.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```js
|
|
9
|
+
* // next.config.js
|
|
10
|
+
* const { withSvger } = require('svger-cli/nextjs');
|
|
11
|
+
*
|
|
12
|
+
* module.exports = withSvger({
|
|
13
|
+
* svger: {
|
|
14
|
+
* source: './src/icons',
|
|
15
|
+
* output: './src/components/icons',
|
|
16
|
+
* framework: 'react',
|
|
17
|
+
* typescript: true
|
|
18
|
+
* },
|
|
19
|
+
* // ... other Next.js config
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { SvgerWebpackPlugin } from './webpack.js';
|
|
24
|
+
import type { NextJsPluginOptions } from '../types/integrations.js';
|
|
25
|
+
/**
|
|
26
|
+
* Next.js plugin configuration wrapper
|
|
27
|
+
*/
|
|
28
|
+
export declare function withSvger(nextConfig?: any): any;
|
|
29
|
+
/**
|
|
30
|
+
* Standalone Next.js webpack plugin
|
|
31
|
+
* Can be used directly in next.config.js webpack function
|
|
32
|
+
*/
|
|
33
|
+
export declare class SvgerNextJsPlugin extends SvgerWebpackPlugin {
|
|
34
|
+
constructor(options?: NextJsPluginOptions);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Helper function to configure SVG imports in Next.js
|
|
38
|
+
* For use in next.config.js
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```js
|
|
42
|
+
* const { configureSvgImports } = require('svger-cli/nextjs');
|
|
43
|
+
*
|
|
44
|
+
* module.exports = {
|
|
45
|
+
* webpack(config, options) {
|
|
46
|
+
* configureSvgImports(config, {
|
|
47
|
+
* framework: 'react',
|
|
48
|
+
* typescript: true
|
|
49
|
+
* });
|
|
50
|
+
* return config;
|
|
51
|
+
* }
|
|
52
|
+
* };
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function configureSvgImports(webpackConfig: any, options?: Partial<NextJsPluginOptions>): void;
|
|
56
|
+
export default withSvger;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Next.js Plugin for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Automatically converts SVG files to framework components in Next.js applications
|
|
5
|
+
* with full SSR support, HMR, and webpack integration.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```js
|
|
9
|
+
* // next.config.js
|
|
10
|
+
* const { withSvger } = require('svger-cli/nextjs');
|
|
11
|
+
*
|
|
12
|
+
* module.exports = withSvger({
|
|
13
|
+
* svger: {
|
|
14
|
+
* source: './src/icons',
|
|
15
|
+
* output: './src/components/icons',
|
|
16
|
+
* framework: 'react',
|
|
17
|
+
* typescript: true
|
|
18
|
+
* },
|
|
19
|
+
* // ... other Next.js config
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { SvgerWebpackPlugin } from './webpack.js';
|
|
24
|
+
import { logger } from '../core/logger.js';
|
|
25
|
+
/**
|
|
26
|
+
* Next.js plugin configuration wrapper
|
|
27
|
+
*/
|
|
28
|
+
export function withSvger(nextConfig = {}) {
|
|
29
|
+
return {
|
|
30
|
+
...nextConfig,
|
|
31
|
+
webpack(config, options) {
|
|
32
|
+
const { isServer } = options;
|
|
33
|
+
// Get svger options from Next.js config
|
|
34
|
+
const svgerOptions = nextConfig.svger || {};
|
|
35
|
+
// Add SVGER webpack plugin
|
|
36
|
+
if (!config.plugins) {
|
|
37
|
+
config.plugins = [];
|
|
38
|
+
}
|
|
39
|
+
// Only run on client build or if explicitly enabled for SSR
|
|
40
|
+
if (!isServer || svgerOptions.ssr !== false) {
|
|
41
|
+
const pluginInstance = new SvgerWebpackPlugin({
|
|
42
|
+
source: svgerOptions.source,
|
|
43
|
+
output: svgerOptions.output,
|
|
44
|
+
framework: svgerOptions.framework || 'react',
|
|
45
|
+
typescript: svgerOptions.typescript,
|
|
46
|
+
config: svgerOptions.config,
|
|
47
|
+
include: svgerOptions.include,
|
|
48
|
+
exclude: svgerOptions.exclude,
|
|
49
|
+
hmr: svgerOptions.hmr,
|
|
50
|
+
generateIndex: svgerOptions.generateIndex,
|
|
51
|
+
});
|
|
52
|
+
config.plugins.push(pluginInstance);
|
|
53
|
+
if (!isServer) {
|
|
54
|
+
logger.info('SVGER Next.js Plugin: Configured for client build');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
logger.info('SVGER Next.js Plugin: Configured for server build');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Add SVG file handling rule
|
|
61
|
+
config.module.rules.push({
|
|
62
|
+
test: /\.svg$/,
|
|
63
|
+
issuer: /\.[jt]sx?$/,
|
|
64
|
+
use: [
|
|
65
|
+
{
|
|
66
|
+
loader: 'svger-cli/webpack-loader',
|
|
67
|
+
options: {
|
|
68
|
+
framework: svgerOptions.framework || 'react',
|
|
69
|
+
typescript: svgerOptions.typescript,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
// Call user's custom webpack config if provided
|
|
75
|
+
if (svgerOptions.webpack && typeof svgerOptions.webpack === 'function') {
|
|
76
|
+
return svgerOptions.webpack(config, options);
|
|
77
|
+
}
|
|
78
|
+
// Call original webpack config if provided
|
|
79
|
+
if (typeof nextConfig.webpack === 'function') {
|
|
80
|
+
return nextConfig.webpack(config, options);
|
|
81
|
+
}
|
|
82
|
+
return config;
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Standalone Next.js webpack plugin
|
|
88
|
+
* Can be used directly in next.config.js webpack function
|
|
89
|
+
*/
|
|
90
|
+
export class SvgerNextJsPlugin extends SvgerWebpackPlugin {
|
|
91
|
+
constructor(options = {}) {
|
|
92
|
+
super({
|
|
93
|
+
source: options.source,
|
|
94
|
+
output: options.output,
|
|
95
|
+
framework: options.framework || 'react',
|
|
96
|
+
typescript: options.typescript,
|
|
97
|
+
config: options.config,
|
|
98
|
+
include: options.include,
|
|
99
|
+
exclude: options.exclude,
|
|
100
|
+
hmr: options.hmr,
|
|
101
|
+
generateIndex: options.generateIndex,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Helper function to configure SVG imports in Next.js
|
|
107
|
+
* For use in next.config.js
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```js
|
|
111
|
+
* const { configureSvgImports } = require('svger-cli/nextjs');
|
|
112
|
+
*
|
|
113
|
+
* module.exports = {
|
|
114
|
+
* webpack(config, options) {
|
|
115
|
+
* configureSvgImports(config, {
|
|
116
|
+
* framework: 'react',
|
|
117
|
+
* typescript: true
|
|
118
|
+
* });
|
|
119
|
+
* return config;
|
|
120
|
+
* }
|
|
121
|
+
* };
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export function configureSvgImports(webpackConfig, options = {}) {
|
|
125
|
+
webpackConfig.module.rules.push({
|
|
126
|
+
test: /\.svg$/,
|
|
127
|
+
issuer: /\.[jt]sx?$/,
|
|
128
|
+
use: [
|
|
129
|
+
{
|
|
130
|
+
loader: 'svger-cli/webpack-loader',
|
|
131
|
+
options: {
|
|
132
|
+
framework: options.framework || 'react',
|
|
133
|
+
typescript: options.typescript !== undefined ? options.typescript : true,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// Default export
|
|
140
|
+
export default withSvger;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Rollup Plugin for SVGER-CLI
|
|
3
|
+
*
|
|
4
|
+
* Automatically converts SVG files to framework components during Rollup builds
|
|
5
|
+
* with full bundle optimization and tree-shaking support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```js
|
|
9
|
+
* // rollup.config.js
|
|
10
|
+
* import { svgerRollupPlugin } from 'svger-cli/rollup';
|
|
11
|
+
*
|
|
12
|
+
* export default {
|
|
13
|
+
* plugins: [
|
|
14
|
+
* svgerRollupPlugin({
|
|
15
|
+
* source: './src/icons',
|
|
16
|
+
* output: './src/components/icons',
|
|
17
|
+
* framework: 'react',
|
|
18
|
+
* typescript: true
|
|
19
|
+
* })
|
|
20
|
+
* ]
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import type { RollupPluginOptions } from '../types/integrations.js';
|
|
25
|
+
/**
|
|
26
|
+
* Rollup Plugin for SVGER-CLI
|
|
27
|
+
*/
|
|
28
|
+
export declare function svgerRollupPlugin(options?: RollupPluginOptions): any;
|
|
29
|
+
export default svgerRollupPlugin;
|