This commit is contained in:
许彦峰
2019-03-15 10:08:39 +08:00
commit e7adf25ccf
75 changed files with 25883 additions and 0 deletions

11
template/core/page.ejs Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
</head>
<body>
<div id="root"></div>
</body>
</html>

60
template/core/tools.js Normal file
View File

@@ -0,0 +1,60 @@
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
exports.htmlPage = (title, filename, chunks, template) => new HtmlWebpackPlugin({
title,
hash: true,
cache: true,
inject: 'body',
filename: './pages/' + filename + '.html',
template: template || path.resolve(__dirname, './page.ejs'),
appMountId: 'app',
chunks
})
exports.cssLoaders = (options = {}) => {
let loaders = {}
let prePprocessors = {
css: {},
postcss: {},
less: { loader: 'less'},
sass: { loader:'sass', options: { indentedSyntax: true } },
scss: { loader:'sass' },
stylus: { loader: 'stylus' },
styl: { loader: 'stylus' }
}
for(let key in prePprocessors) {
let loader = [{
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production'
}
}]
if (prePprocessors[key].loader) {
loader.push({
loader: prePprocessors[key].loader + '-loader',
options: Object.assign({}, prePprocessors[key].options, { sourceMap: options.sourceMap })
})
}
if (options.extract) {
loaders[key] = ExtractTextPlugin.extract({ use: loader, fallback: 'vue-style-loader' })
} else {
loaders[key] = ['vue-style-loader'].concat(loader)
}
}
return loaders;
}
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}

View File

@@ -0,0 +1,106 @@
const path = require('path')
const webpack = require('webpack')
const ChromeReloadPlugin = require('wcer')
const {cssLoaders, htmlPage} = require('./tools')
const CopyWebpackPlugin = require('copy-webpack-plugin')
let resolve = dir => path.join(__dirname, '..', 'src', dir)
module.exports = {
entry: {
tab: resolve('./tab'),
popup: resolve('./popup'),
options: resolve('./options'),
content: resolve('./content'),
devtools: resolve('./devtools'),
background: resolve('./backend'),
panel: resolve('./devtools/panel'),
inject: resolve('./content/inject'),
},
output: {
path: path.join(__dirname, '..', 'build'),
publicPath: '/',
filename: 'js/[name].js',
chunkFilename: 'js/[id].[name].js?[hash]',
library: '[name]'
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [path.join(__dirname, '..', 'src'), path.join(__dirname, '..', 'test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
extractCSS: true,
loaders: {
...cssLoaders(),
js: { loader: 'babel-loader' }
},
transformToRequire: {
video: 'src',
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [path.join(__dirname, '..', 'src'), path.join(__dirname, '..', 'test')],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
]
},
plugins: [
htmlPage('home', 'app', ['tab']),
htmlPage('popup', 'popup', ['popup']),
htmlPage('panel', 'panel', ['panel']),
htmlPage('devtools', 'devtools', ['devtools']),
htmlPage('options', 'options', ['options']),
htmlPage('background', 'background', ['background']),
new CopyWebpackPlugin([{ from: path.join(__dirname, '..', 'static') }]),
new ChromeReloadPlugin({
port: 9090,
manifest: path.join(__dirname, '..', 'src', 'manifest.js')
}),
],
performance: { hints: false },
}

View File

@@ -0,0 +1,21 @@
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpack = require('./webpack.base')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const {styleLoaders} = require('./tools')
module.exports = merge(baseWebpack, {
// cheap-module-eval-source-map быстрее для разработки
watch: true,
module: {
rules: styleLoaders({ sourceMap: false })
},
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"development"'
}),
new FriendlyErrorsPlugin()
]
})

View File

@@ -0,0 +1,47 @@
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpack = require('./webpack.base')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const {styleLoaders} = require('./tools')
module.exports = merge(baseWebpack, {
devtool: '#cheap-module-eval-source-map',
module: {
rules: styleLoaders({ extract: true, sourceMap: true })
},
plugins: [
new CleanWebpackPlugin(['build/*.*']),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
new ExtractTextPlugin({
filename: 'css/[name].[contenthash].css'
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
})