Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
liutao committed Dec 23, 2019
1 parent e75733e commit 209f7ff
Show file tree
Hide file tree
Showing 18 changed files with 3,530 additions and 699 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules/
.DS_Store
.cache/
dist/
dist/
lib/
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/example/main.js",
"skipFiles": [
"<node_internals>/**"
]
}


]
}
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# message-webpack-plugin

一个处理消息的webpack插件。
:kissing_heart:一个处理消息的webpack插件。

:point_right:
[![github](https://img.shields.io/github/release-date/imccode/message-webpack-plugin.svg)](https://github.com/imccode/message-webpack-plugin/releases)
[![npm-version](https://img.shields.io/npm/v/message-webpack-plugin.svg)](https://www.npmjs.com/package/message-webpack-plugin)
[![webpack](https://img.shields.io/badge/webpack-%3E%20%3D%204.0.0-blue.svg)](https://webpack.js.org/)
[![nodejs](https://img.shields.io/badge/node-%3E%20%3D%2010.0.0-blue.svg)](https://nodejs.org/)
[![license](https://img.shields.io/npm/l/message-webpack-plugin.svg)](https://www.npmjs.com/package/message-webpack-plugin)
[![pull request](https://img.shields.io/badge/PRs-welcome-green.svg)](https://github.com/imccode/message-webpack-plugin/pulls)

## 安装获取

Expand Down
1 change: 1 addition & 0 deletions example/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('start')
9 changes: 9 additions & 0 deletions example/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const webpack = require('webpack')
const ServeWebpackPlugin = require('serve-webpack-plugin')
const MessageWebpackPlugin = require('../lib')

webpack({
entry: './example/entry.js',
mode: 'development',
plugins: [new ServeWebpackPlugin(), new MessageWebpackPlugin()]
}).watch({}, () => {})
13 changes: 0 additions & 13 deletions prettier.config.js

This file was deleted.

117 changes: 117 additions & 0 deletions src/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import chalk from 'chalk'
import { Stats } from 'webpack'

const friendlySyntaxErrorLabel = 'Syntax error:'
const friendlyParsingErrorLabel = 'Parsing error:'

const hasError = (message: string) =>
message.includes(friendlySyntaxErrorLabel) || message.includes(friendlyParsingErrorLabel)

const lineErrorString = (label: string, message: string, line: string, columm: string) =>
`${chalk.bold(`Line ${line}:${columm}`)} ${label} ${message.trim()}`

// Cleans up webpack error messages.
const formatMessage = (message: string): string => {
let lines = message.split('\n')

lines = lines.filter(line => {
if (/Module [A-z ]+\(from/.test(line)) return false
if (/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm.test(line)) return false
if (/^\s*at\s<anonymous>(\n|$)/gm.test(line)) return false
if (line.includes('Module failed because of a eslint error')) return false
return true
})

lines = lines.map(line => {
if (line.indexOf('Thread Loader') === 0) return ''

if (line === 'SyntaxError') return ''

// SyntaxError: ./App.js: Unexpected token, expected "{" (5:14)"
let parsingError = /(SyntaxError: )*\S+:(( \S+)*) \((\d+):(\d+)\)/.exec(line)
if (parsingError) {
const [, , errorMessage, , errorLine, errorColumn] = parsingError
return lineErrorString(friendlySyntaxErrorLabel, errorMessage, errorLine, errorColumn)
}

// (7:24) Unknown word
parsingError = /^\((\d+):(\d+)\)(( \S+)*)/.exec(line)
if (parsingError) {
const [, errorLine, errorColumn, errorMessage] = parsingError
return lineErrorString(friendlySyntaxErrorLabel, errorMessage, errorLine, errorColumn)
}

return line
})

message = lines.join('\n')

message = message.replace(
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
)
// Clean up export errors
message = message.replace(
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$2'.`
)
message = message.replace(
/^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$2' does not contain a default export (imported as '$1').`
)
message = message.replace(
/^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
`Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
)
lines = message.split('\n')

if (lines.length > 2 && lines[1].trim() === '') {
lines.splice(1, 1)
}
lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, '$1')

if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
lines = [
lines[0],
lines[1]
.replace('Error: ', '')
.replace('Module not found: Cannot find file:', 'Cannot find file:')
]
}

if (lines[1] && lines[1].match(/Cannot find module.+node-sass/)) {
lines[1] = 'To import Sass files, you first need to install node-sass.\n'
lines[1] += 'Run `npm install node-sass` or `yarn add node-sass` inside your workspace.'
}

lines[0] = chalk.cyan(lines[0])

message = lines.join('\n')

lines = lines.filter(
(line, index, arr) => index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim()
)

// Reassemble the message
message = lines.join('\n')
return message.trim()
}

function formatWebpackMessages(statsJson: Stats.ToJsonOutput) {
const formattedErrors: string[] = statsJson.errors.map(message => formatMessage(message))
const formattedWarnings: string[] = statsJson.warnings.map(message => formatMessage(message))

const warnings = formattedWarnings
let errors = formattedErrors

if (errors.some(hasError)) {
errors = errors.filter(hasError)
}

return {
warnings,
errors
}
}

export default formatWebpackMessages
57 changes: 57 additions & 0 deletions src/hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import chalk from 'chalk'
import { Compiler } from 'webpack'
import formatWebpackMessages from './format'
import { MessageWebpackPluginOptions } from './types'

const pluginName = 'MessageWebpackPlugin'

export default (options: MessageWebpackPluginOptions = {}, compiler: Compiler) => {
const { invalid, done } = compiler.hooks

const isTTY = process.stdout.isTTY
const clearConsole = () =>
process.stdout.write(process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H')

invalid.tap(pluginName, () => {
if (isTTY && compiler.options.mode === 'development') clearConsole()
console.log(`\n🛠 ${chalk.green('正在编译...')}`)
})

done.tap(pluginName, stats => {
if (isTTY && compiler.options.mode === 'development') clearConsole()

if (!stats.hasErrors() && !stats.hasWarnings()) {
console.log(`\n✅ ${chalk.green('编译成功!')}`)
this.options.onSuccess && this.options.onSuccess()
return
}

const message = formatWebpackMessages(
stats.toJson({
all: false,
warnings: true,
errors: true
})
)

if (message.errors.length > 0) {
console.log(`\n⭕️ ${chalk.red('编译失败!')}\n`)
if (this.options.onError) {
this.options.onError(stats.compilation.errors)
} else {
console.log(message.errors.join('\n\n'))
}
return
}

if (message.warnings.length > 0) {
console.log(`\n❔ ${chalk.yellow('编译警告!')}\n`)
if (this.options.onWarning) {
this.options.onWarning(stats.compilation.warnings)
} else {
console.log(message.warnings.join('\n\n'))
}
return
}
})
}
41 changes: 41 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Compiler } from 'webpack'
import { MessageWebpackPluginOptions } from './types'
import formatWebpackMessages from './format'
import mergeOptions from './mergeOptions'
import hook from './hook'

/**
* 消息webpack插件
*/
class MessageWebpackPlugin {
options: MessageWebpackPluginOptions = {}

constructor(options: MessageWebpackPluginOptions = {}) {
this.options = mergeOptions(options)
}

/**
* 注入默认配置
* @param compiler
*/
inject(compiler: Compiler) {
compiler.options.stats = {
all: false
}
compiler.options.performance = false
}

/**
* 执行插件
* @param compiler
*/
apply(compiler: Compiler) {
this.inject(compiler)
hook(this.options, compiler)
}
}

export * from './types'
export { MessageWebpackPlugin, formatWebpackMessages }
export default MessageWebpackPlugin
module.exports = MessageWebpackPlugin
15 changes: 15 additions & 0 deletions src/mergeOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MessageWebpackPluginOptions } from './types'

// 默认配置
export const defaultOptions: MessageWebpackPluginOptions = {
servePort: 33333
}

export default (options: MessageWebpackPluginOptions = {}) => {
const mergeOptions: MessageWebpackPluginOptions = {
...defaultOptions,
...options
}

return mergeOptions
}
19 changes: 19 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* message-webpack-plugin webpack消息插件
*/
export interface MessageWebpackPluginOptions {
/** devServe服务消息端口 */
servePort?: number
/**
* 编译完成回调
*/
onSuccess?(): void
/**
* 编译失败回调
*/
onError?(errors: any[]): void
/**
* 编译警告回调
*/
onWarning?(warnings: any[]): void
}
6 changes: 6 additions & 0 deletions types/format.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Stats } from 'webpack';
declare function formatWebpackMessages(statsJson: Stats.ToJsonOutput): {
warnings: string[];
errors: string[];
};
export default formatWebpackMessages;
4 changes: 4 additions & 0 deletions types/hook.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Compiler } from 'webpack';
import { MessageWebpackPluginOptions } from './types';
declare const _default: (options: MessageWebpackPluginOptions, compiler: Compiler) => void;
export default _default;
23 changes: 23 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Compiler } from 'webpack';
import { MessageWebpackPluginOptions } from './types';
import formatWebpackMessages from './format';
/**
* 消息webpack插件
*/
declare class MessageWebpackPlugin {
options: MessageWebpackPluginOptions;
constructor(options?: MessageWebpackPluginOptions);
/**
* 注入默认配置
* @param compiler
*/
inject(compiler: Compiler): void;
/**
* 执行插件
* @param compiler
*/
apply(compiler: Compiler): void;
}
export * from './types';
export { MessageWebpackPlugin, formatWebpackMessages };
export default MessageWebpackPlugin;
4 changes: 4 additions & 0 deletions types/mergeOptions.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { MessageWebpackPluginOptions } from './types';
export declare const defaultOptions: MessageWebpackPluginOptions;
declare const _default: (options?: MessageWebpackPluginOptions) => MessageWebpackPluginOptions;
export default _default;
19 changes: 19 additions & 0 deletions types/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* message-webpack-plugin webpack消息插件
*/
export interface MessageWebpackPluginOptions {
/** devServe服务消息端口 */
servePort?: number;
/**
* 编译完成回调
*/
onSuccess?(): void;
/**
* 编译失败回调
*/
onError?(errors: any[]): void;
/**
* 编译警告回调
*/
onWarning?(warnings: any[]): void;
}
Loading

0 comments on commit 209f7ff

Please sign in to comment.