blob: 1186066e7f718184407ff1083815a279a74f9263 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const path = require('path')
const glob = require('globby')
const webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const isProduction = process.env.NODE_ENV !== 'development'
const resolve = dir => path.join(__dirname, '..', dir)
const assetsDir = resolve('src')
const distDir = resolve('dist')
const viewDir = resolve('src/view')
function moduleName (modules) {
let filename = path.basename(modules)
let parts = filename.split('.')
parts.pop()
filename = parts.join('.')
return path.dirname(modules) + '/' + filename
}
const jsEntry = (() => {
const obj = {}
const files = glob.sync(['js/conf/*/!(_*).js'], { cwd: assetsDir })
files.forEach(val => {
let parts = val.split(/[\\/]/)
parts.shift()
parts.shift()
let modules = parts.join('/')
let entry = moduleName(modules)
obj[entry] = ['babel-polyfill', val]
})
return obj
})()
const minifierConfig = isProduction ? {
removeComments: true,
removeCommentsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
minifyJS: true,
removeScriptTypeAttributes: true,
maxLineLength: 1024
} : false
const getPageEntry = view => jsEntry[view] ? view : ''
// Redirect output page
const pageRewriter = {
'view/home/index.*': 'index.html'
}
const isEmpty = o => {
for (let k in o) {
if (o.hasOwnProperty(k)) {
return
}
}
return true
}
const unixPath = v => v.replace(/\\/g, '/')
const rewriterPath = p => {
if (isEmpty(pageRewriter)) {
return
}
for (let k in pageRewriter) {
let regx = new RegExp(k)
if (regx.test(unixPath(p))) {
return pageRewriter[k]
}
}
}
const version = new Date().getTime();
const pages = glob.sync(['*/!(_*).html'], { cwd: viewDir }).map(p => {
let pagePath = `${path.join(viewDir, p)}`
let newPagePath = rewriterPath(pagePath)
let entry = getPageEntry(p.replace('.html', ''))
let chunks = ['common']
if (entry) {
chunks.push(entry)
}
return new HtmlWebpackPlugin({
filename: newPagePath || path.join('view', p),
template: `${path.join('src/view', p)}`,
cache: true,
favicon:'./favicon.png',
inject: true,
hash: version,
chunks: chunks,
minify: minifierConfig
})
})
const baseConfig = {
entry: jsEntry,
output: {
path: distDir,
publicPath: '/',
filename: 'js/[name].[chunkhash:7]'+version+'.js'
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: true
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
hotReload: !isProduction
}
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheIdentifier: true
}
}
]
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: !isProduction,
},
},
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: (loader) => [
require('autoprefixer')({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
]
}),
require('cssnano')
]
}
},
'sass-loader'
]
},
{
test: /\.(png|jpe?g|gif|svg|cur)(\?.*)?$/,
loader: 'file-loader',
options: {
esModule: false,
name: 'images/[name].[ext]?[hash]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
esModule: false,
limit: 10000,
// publicPath: distDir,
name: 'font/[name].[hash:7].[ext]'
}
}
]
},
resolve: {
modules: [
resolve('node_modules'),
resolve('src'),
resolve('src/js')
],
alias: {
'@': resolve('src/js'),
'~': resolve('src/lib'),
'jquery':'jquery/dist/jquery.min.js',
'jquery-ui': 'jquery-ui'
},
extensions: ['*', '.js', 'json', '.vue', '.scss']
},
plugins: [
new VueLoaderPlugin(),
new webpack.ProvidePlugin({ vue: 'Vue', _: 'lodash',jQuery:"jquery/dist/jquery.min.js",$:"jquery/dist/jquery.min.js" }),
new webpack.DefinePlugin({
PUBLIC_PATH: JSON.stringify(process.env.PUBLIC_PATH ? process.env.PUBLIC_PATH : '')
}),
...pages
]
}
module.exports = {
isProduction,
assetsDir,
distDir,
baseConfig
}