Skip to content

feat: 压缩后图片资源重新写入到 webpack compilation 构建资源中 #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const Figures = require("figures");
const Ora = require("ora");
const SchemaUtils = require("schema-utils");
const { ByteSize, RoundNum } = require("trample/node");
const { RawSource } = require("webpack-sources");

const { IMG_REGEXP, PLUGIN_NAME } = require("../util/getting");
const { RandomHeader } = require("../util/setting");
Expand All @@ -18,32 +19,41 @@ module.exports = class TinyimgWebpackPlugin {
apply(compiler) {
const { enabled, logged } = this.opts;
SchemaUtils(Schema, this.opts, { name: PLUGIN_NAME });
enabled && compiler.hooks.emit.tap(PLUGIN_NAME, compilation => {
enabled && compiler.hooks.emit.tapPromise(PLUGIN_NAME, compilation => {
const imgs = Object.keys(compilation.assets).filter(v => IMG_REGEXP.test(v));
if (!imgs.length) return Promise.resolve();
const promises = imgs.map(v => this.compressImg(compilation.assets, v));
const spinner = Ora("Image is compressing......").start();
return Promise.all(promises).then(res => {
spinner.stop();
logged && res.forEach(v => console.log(v));
});
const spinner = Ora("Images is compressing......").start();
return new Promise(resolve => {
Promise.all(promises).then(res => {
spinner.stopAndPersist({text: 'Images compression done', symbol: '✅'});
// 输出错误,如果有的话
res.filter(info => logged || info.status === 'fail').forEach(v => console.log(v.msg));
resolve()
})
})
});
}
async compressImg(assets, path) {
try {
const file = assets[path].source();
const obj = await this.uploadImg(file);

if (obj.isError) {
return Promise.resolve({msg: `${Figures.cross} [${Chalk.yellowBright(path)}] compression failed. ${obj.msg}`, status: 'fail'});
}

const data = await this.downloadImg(obj.output.url);
// 写回到原来资源中
assets[path] = new RawSource(Buffer.alloc(data.length, data, 'binary'))
const oldSize = Chalk.redBright(ByteSize(obj.input.size));
const newSize = Chalk.greenBright(ByteSize(obj.output.size));
const ratio = Chalk.blueBright(RoundNum(1 - obj.output.ratio, 2, true));
const dpath = assets[path].existsAt;
const msg = `${Figures.tick} Compressed [${Chalk.yellowBright(path)}] completed: Old Size ${oldSize}, New Size ${newSize}, Optimization Ratio ${ratio}`;
Fs.writeFileSync(dpath, data, "binary");
return Promise.resolve(msg);
return Promise.resolve({msg, status: 'success'});
} catch (err) {
const msg = `${Figures.cross} Compressed [${Chalk.yellowBright(path)}] failed: ${Chalk.redBright(err)}`;
return Promise.resolve(msg);
return Promise.resolve({msg, status: 'fail'});
}
}
downloadImg(url) {
Expand All @@ -63,8 +73,12 @@ module.exports = class TinyimgWebpackPlugin {
const opts = RandomHeader();
return new Promise((resolve, reject) => {
const req = Https.request(opts, res => res.on("data", data => {
const obj = JSON.parse(data.toString());
obj.error ? reject(obj.message) : resolve(obj);
try {
const obj = JSON.parse(data.toString());
obj.error ? reject({isError: true, msg: obj.message}) : resolve(obj);
} catch (error) {
reject({isError: true, msg: error.message || '图片解析失败'})
}
}));
req.write(file, "binary");
req.on("error", e => reject(e));
Expand Down
Binary file removed test/src/img/pig-3.jpg
Binary file not shown.
Binary file added test/src/img/pig-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
background-image: url("./img/pig-2.jpg");
}
&-3 {
background-image: url("./img/pig-3.jpg");
background-image: url("./img/pig-3.png");
}
}