Skip to content

Commit 09a453e

Browse files
committed
Merge branch 'master' of https://github.com/q2g/q2g-build
2 parents 34bb413 + 17c2492 commit 09a453e

File tree

8 files changed

+1111
-455
lines changed

8 files changed

+1111
-455
lines changed

src/builder/extension-builder/extension-builder.ts

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,8 @@ export class ExtensionBuilder extends WebpackBuilder {
8686
const config = this.webpackService.getConfig();
8787
const fileName = config.getOutFileName();
8888
const outDir = config.getOutDirectory();
89-
9089
const plugins = [
91-
new LogPlugin(),
92-
new CleanWebpackPlugin({
93-
cleanAfterEveryBuildPatterns: ["!**/wbfolder.wbl"],
94-
}),
95-
new CopyWebpackPlugin({
96-
patterns: this.getBinaryFiles()
97-
}),
90+
...super.loadWebpackPlugins(),
9891
new QextFilePlugin(this.extensionService.getQextConfiguration()),
9992
new ZipWebpackPlugin({
10093
filename: `${fileName}.zip`,
@@ -105,27 +98,24 @@ export class ExtensionBuilder extends WebpackBuilder {
10598
if (config.getCi()) {
10699
plugins.push(this.createDeployPlugin(fileName));
107100
}
108-
109101
return plugins;
110102
}
111103

112-
/**
113-
* get binary files which should copy to dist folder
114-
*
115-
* @private
116-
* @returns {Pattern[]}
117-
* @memberof ExtensionBuilder
118-
*/
119-
private getBinaryFiles(): Pattern[] {
104+
protected getCleanWebpackPluginOptions(): IDataNode {
105+
const options = super.getCleanWebpackPluginOptions();
106+
return {...options, cleanAfterEveryBuildPatterns: ["!**/wbfolder.wbl"]};
107+
}
120108

121-
const binFiles = [
109+
protected getCopyWebpackPluginAssets(): Pattern[] {
110+
const copyPaths = super.getCopyWebpackPluginAssets();
111+
const binFiles = [
112+
...copyPaths,
122113
{ from: "wbfolder.wbl", to: "wbfolder.wbl" },
123114
];
124115

125116
if (existsSync(resolve(this.webpackService.getConfig().getProjectRoot(), "preview.png"))) {
126117
binFiles.push({ from: "preview.png", to: "preview.png" });
127118
}
128-
129119
return binFiles;
130120
}
131121

src/builder/webpack-builder/data/webpack.option.rules.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { ValidationHelper } from "../../../helper";
33

44
export const WebpackOptionRules: IOptionRuleSet = {
55

6+
rootDir: {
7+
required: true,
8+
},
9+
610
entryFile: {
711
required: true,
812
},
@@ -21,6 +25,17 @@ export const WebpackOptionRules: IOptionRuleSet = {
2125
validatorFn: ValidationHelper.notEmptyAndNoWhitespace,
2226
},
2327

28+
binaries: {
29+
required: false,
30+
validatorFn: (value) => {
31+
const isValid = Array.isArray(value);
32+
return {
33+
error: isValid ? [] : ["requires an array of relative paths, files"],
34+
isValid,
35+
};
36+
},
37+
},
38+
2439
watch: {
2540
required: false,
2641
},
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { existsSync, lstatSync, PathLike, readFileSync } from "fs";
2+
import { basename, extname, resolve } from "path";
3+
4+
/**
5+
* get image source data as bas64 format
6+
*/
7+
function getSourceData(path: PathLike): string {
8+
const base64Source = Buffer.from(readFileSync(path)).toString("base64");
9+
const imageType = extname(basename(path.toString())).toLowerCase();
10+
11+
switch (imageType.substr(1)) {
12+
case "jpg": case "jpeg":
13+
return `data:image/jpg;base64,${base64Source}`;
14+
15+
case "gif":
16+
return `data:image/gif;base64,${base64Source}`;
17+
18+
case "svg":
19+
return `data:image/svg+xml;base64,${base64Source}`;
20+
21+
default:
22+
return `data:image/png;base64,${base64Source}`;
23+
}
24+
}
25+
26+
/**
27+
* find all matches from html loader,
28+
* which one replace an image path with require("..../file");
29+
*
30+
* and replace by base64 data source
31+
*/
32+
export default function imageToBase64Loader(source) {
33+
34+
/**
35+
* get all require imports from <img src=\"" + require("./assets/path/image") + "\" ...>
36+
* and extract only image path from it which will converted into base 64 and replace
37+
* full match by
38+
*
39+
* <img src=\"base64SourceString\" ...>
40+
*/
41+
const requiredModules = /<img src=\\"(?:".*?require\(")([^"]+)(?:".*?(?=\\"\s))/g;
42+
const replacedSource = source.replace(requiredModules, (match, relativePath) => {
43+
const imagePath = resolve(this.context, relativePath);
44+
if (existsSync(imagePath) && lstatSync(imagePath).isFile) {
45+
return `<img src=\\"${getSourceData(imagePath)}`;
46+
}
47+
return match;
48+
});
49+
return replacedSource;
50+
}

src/builder/webpack-builder/model/webpack-config.model.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { ConfigModel } from "../../../model/config.model";
1010
*/
1111
export class WebpackConfigModel extends ConfigModel {
1212

13+
private binaries: string[] = [];
14+
1315
/**
1416
* envrionment
1517
*
@@ -113,6 +115,8 @@ export class WebpackConfigModel extends ConfigModel {
113115

114116
private extensionCi: boolean;
115117

118+
private rootDir: string;
119+
116120
/**
117121
* get source directory which where the project is located
118122
*
@@ -203,6 +207,22 @@ export class WebpackConfigModel extends ConfigModel {
203207
return this.plugins;
204208
}
205209

210+
public setRootDir(path: string) {
211+
this.rootDir = path;
212+
}
213+
214+
public getRootDir(): string {
215+
return this.rootDir;
216+
}
217+
218+
public setBinaries(paths: string[]) {
219+
this.binaries = paths;
220+
}
221+
222+
public getBinaries(): string[] {
223+
return this.binaries;
224+
}
225+
206226
/**
207227
* set optimizations for webpack
208228
*
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as PluginClean from "clean-webpack-plugin";
2+
import * as WebpackCopyPlugin from "copy-webpack-plugin";
23

4+
export const CopyWebpackPlugin = WebpackCopyPlugin;
35
export const CleanWebpackPlugin = PluginClean;
46
export * from "./log.plugin";

src/builder/webpack-builder/templates/module-rules.config.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ const moduleRules: ModuleOptions = {
1111
{ loader: "clean-requirejs-imports.loader" },
1212
{ loader: "sanitize-html-imports.loader" },
1313
],
14-
}, {
15-
test: /text!.*\.html$/,
16-
use: [{
17-
loader: "raw-loader",
18-
}],
1914
}, {
2015
test: /.*\.html$/,
21-
use: [{
22-
loader: "raw-loader",
23-
}],
16+
use: [
17+
{
18+
loader: "image-to-base64.loader",
19+
},
20+
{
21+
loader: "html-loader",
22+
options: {
23+
}
24+
},
25+
],
2426
}, {
2527
loader: "json-loader",
2628
test: /\.json/,

src/builder/webpack-builder/webpack-builder.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { CleanWebpackPlugin } from "clean-webpack-plugin";
2+
import { Pattern } from "copy-webpack-plugin";
23
import { basename, resolve } from "path";
34
import * as TerserWebpackPlugin from "terser-webpack-plugin";
45
import { Compiler, Module, AutomaticPrefetchPlugin, ModuleOptions } from "webpack";
56
import { IBuilder, IBuilderEnvironment } from "../../api";
67
import { IDataNode } from "../../api/data-node";
78
import { WebpackConfigModel } from "./model/webpack-config.model";
8-
import { LogPlugin } from "./plugins";
9+
import { CopyWebpackPlugin, LogPlugin } from "./plugins";
910
import { WebpackService } from "./service/webpack.service";
1011

1112
/**
@@ -44,12 +45,10 @@ export class WebpackBuilder implements IBuilder {
4445
* @memberof WebpackBuilder
4546
*/
4647
public configure(config: any): void {
47-
4848
/** hotfix rewrite entry file to be an object, se we can apply multiple entry files */
4949
const entryFile = {};
50-
entryFile[config.outFileName || basename(config.entryFile, "ts")] = config.entryFile;
50+
entryFile[config.outFileName || basename(config.entryFile, "ts")] = resolve(config.rootDir, config.entryFile),
5151
config.entryFile = entryFile;
52-
5352
this.webpackService.setOptions({
5453
...this.initialConfig,
5554
...config,
@@ -184,13 +183,13 @@ export class WebpackBuilder implements IBuilder {
184183
* @memberof WebpackBuilder
185184
*/
186185
protected loadWebpackPlugins(): AutomaticPrefetchPlugin[] {
187-
188186
/** cast to any to fix typings */
189-
const cleanWebpackPlugin: AutomaticPrefetchPlugin = new CleanWebpackPlugin() as any;
190-
191187
const plugins: AutomaticPrefetchPlugin[] = [
192188
new LogPlugin(),
193-
cleanWebpackPlugin,
189+
new CleanWebpackPlugin(this.getCleanWebpackPluginOptions()),
190+
new CopyWebpackPlugin({
191+
patterns: this.getCopyWebpackPluginAssets()
192+
}),
194193
];
195194
return plugins;
196195
}
@@ -206,4 +205,17 @@ export class WebpackBuilder implements IBuilder {
206205
const moduleRules: any = await import("./templates/module-rules.config");
207206
return moduleRules.default;
208207
}
208+
209+
protected getCleanWebpackPluginOptions(): IDataNode {
210+
return {};
211+
}
212+
213+
protected getCopyWebpackPluginAssets(): Pattern[] {
214+
const binaries = this.webpackService.getConfig().getBinaries();
215+
if (binaries && Array.isArray(binaries)) {
216+
const rootDir = this.webpackService.getConfig().getRootDir();
217+
return binaries.map((binary) => ({ from: `${rootDir}/${binary}`, to: binary }));
218+
}
219+
return [];
220+
}
209221
}

0 commit comments

Comments
 (0)