wox-cli
Version:
scaffold for create component, toolkit and so on
216 lines (197 loc) • 5.35 kB
JavaScript
'use strict';
const path = require('path');
const find = require('find');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { publicPath } = require('./publicPath.config');
function resolve (dir) {
return path.join(__dirname, '.', dir);
}
const files = find.fileSync('./src/pages/');
const entrys = {};
const entrysArr = [];
const re = /[\w\W]*src\/([\w\W]+)\.js$/;
const pluginList = [];
for (let i = 0; i < files.length; i++) {
if (/\.entry\.js$/.test(files[i])) {
const filei = files[i].replace(re, '$1');
entrys[filei] = ['babel-polyfill', `./${files[i]}`];
entrysArr.push(filei);
}
}
// 根据入口js文件生成对应的html文件
for (let j = 0; j < entrysArr.length; j++) {
const pathname = path.basename(entrysArr[j]).split('.')[0];
const conf = {
filename: `${pathname}.html`,
template: './index.html',
inject: 'body',
favicon: './favicon.ico',
title: pathname,
chunks: ['common', entrysArr[j]],
};
pluginList.push(new HtmlWebpackPlugin(conf));
}
pluginList.push(
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'js/common/common.js',
chunks: entrysArr,
minChunks: Math.ceil(entrysArr.length * 2 / 3),
})
)
module.exports = {
context: path.resolve(__dirname, './'),
entry: entrys,
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].js',
publicPath: '/'
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
plugins: pluginList,
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: true
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: cssLoaders({
sourceMap: true,
extract: process.env.NODE_ENV === 'production'
}),
cssSourceMap: true,
cacheBusting: true,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 1024,
name: 'images/[name].[hash:7].[ext]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 1024,
name: 'media/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 1024,
name: 'fonts/[name].[hash:7].[ext]'
}
},
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
}
].concat(process.env.NODE_ENV === 'production' ? styleLoaders({sourceMap: true, usePostCSS: true, extract: true}) : styleLoaders({sourceMap: true, usePostCSS: true}))
},
node: {
setImmediate: false,
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
};
// utils
function cssLoaders(options) {
options = options || {};
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap,
alias: {
'./@': path.resolve(__dirname, './src')
}
}
};
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
};
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath
});
} else {
return ['vue-style-loader'].concat(loaders);
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
};
}
function styleLoaders(options) {
const output = [];
const loaders = cssLoaders(options);
for (const extension in loaders) {
const loader = loaders[extension];
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
});
}
return output;
}