
批处理
前端现在在做项目的时候大多数遇到的都是单页面应用,但有时需要做多页面的时候,会把单页拿过来修改成多页面,如果代码多了,对单页或多页的配置可能会混乱,那么有没有更好的方式能把单页面和多页面不同的配置代码分开,能更清楚的分辩他们的区别,这里是利用 批处理 对前端构建进行部署 git地址 目录分为三块
single //单页代码 share // 共用代码 many //多页代码
只需要用到 批处理 对其中两者进行合并就能生成想要的单页或多页应用,提示需要安装国内的 npm淘宝镜像
如果未安装的需要自行修改build.bat里的命令行 call cnpm install 为 call npm install
如下所示:

先选择存放路径,输入项目名,选择要生成的是单页还是多页

这里以单页为示例,其实就是简单的对文件进行复制,复制完成后会自动安装依赖

安装完依赖后还会自动运行项目 如上开启的项目端口为8080
目录如下

webpack4 共同配置(share)
这里用到了最新的webpack4.0,它简化了很多配置,多线程输出,更快的构建能力,大大提高了开发的效率
首先看下配置文件 config.js
const path = require('path'),
config = {
//开发环境配置
dev: {
port: 8080,
// 接口代理
proxyTable: {
'/v2': {
target: 'https://api.douban.com',
changeOrigin: true
},
},
},
//生产环境配置
build: {
packName: 'myProjcet', //项目打包后名称
outputPath: '', //打包后项目这里有开发环境下的接口代理,
生产环境的目录名称和路径
还有可选的是否转换页面字体为 rem 和 eslint 语法检测
eslint 校验是默认的规则校验
它还有其它的三种 通用规则
可根据自身喜好去设置
然后是 utils.js 工具方法
module.exports = {
/***
* 获取src一级目录
*/
getFiles() {
const files = glob.sync('src/**/'),
arr = [];
files.forEach((filepath) => {
let name = filepath.split('/')[1];
if (name) {
arr.push(...[name]);
}
})
let obj = {};
if (arr.length) {
[...new Set(arr)].map(item => {
obj[`@${item}`] = path.join(__dirname, `../src/${item}`);
})
}
return obj
},
/**
* 多页面命名 获取每个多页对应的js名命名
* **/
getFileName() {
let fileName = glob.sync('src/**/index.js');
entryArr = {};
fileName.forEach(function(path) {
let arr = path.split('/');
let name = arr[arr.length - 2];
entryArr[name] = './' + path;
})
return entryArr;
},
/***
* 静态目录存放路径
*/
assetsPath(_path) {
return path.posix.join(config.build.resourcesShortPath, _path);
},
copyDir(source, target) {
rm('-rf', target);
mkdir('-p', target);
cp('-R', source, target);
}
}再来看在开发和生产共用的代码 webpack.base.conf.js
首先看下一些基本的对 vue、css、js 这些loader的操作
rules: [
{ test: /\.vue$/, loader: 'vue-loader', },
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
{
test: /\.js$/,
loader: !process.env.NODE_ENV ? 'happypack/loader?id=happy-babel' : 'babel-loader',
//loader: 'babel-loader',
exclude: /(node_modules|lib)/,
include: [ // 表示只解析以下目录,减少loader处理范围
path.resolve(__dirname, '../src'),
],
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [{
loader: 'file-loader',
options: {
//生产环境真实路径
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}]
},
{
test: /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
//生产环境真实路径
name: utils.assetsPath('image/[name].[hash:7].[ext]')
}
}
},
]嗯都给了注释,要注意的是 css、less、scss 的loader顺序,不要写反因为他是从前往后这样编译的 如果找不到前面的后面的loader也就无法执行 js 的loader用了一段这个
!process.env.NODE_ENV ? 'happypack/loader?id=happy-babel' : 'babel-loader',
因为在生产环境下打包时 js loader的编译会很慢,所以开启了多线程去处理 js loader的编译
HappyPack = require('happypack'),
os = require('os'),
happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }),
//利用多线程解决js loader编译过程耗时 除scss无法使用 css、vue都可使用 (webpack4本来就是多线程)
createHappyPlugin = (id, loaders) => new HappyPack({
id: id,
loaders: loaders,
threadPool: happyThreadPool,
verbose: true, //允许 HappyPack 需要在 plugins 下加上下面这段
createHappyPlugin('happy-babel', [{
loader: 'babel-loader',
options: {
babelrc: true,
cacheDirectory: true // 启用缓存
}
}]),happy-babel 就是找到上面loader的id,但因为webpack4本来就是多线程的,这样做可能多此一举,暂时没有测试过量大时编译效果
还有这个
new VueLoaderPlugin()
在 vue-loader 版本为15.0以后都要加上
其它在升级到webpack4.0后还是有不少的坑,
就比如4之前可用的合并加载文件
new webpack.optimize.MinChunkSizePlugin({minChunkSize: 30000}),这个已经整合到 splitChunks 里面去了,再用的话就会冲突报错
因为之前没有留意 用3升4的过程中没有删除它,所以大家要重新配置4的时候还是重新一步步配置,否则很多报错都莫名其妙,接着往下看
if (!process.env.NODE_ENV) {
for (let i = 1; i < 3; i++) {
//使用mini-css-extract-plugin在生产环境要把style-loader覆盖,它们会有冲突
config.module.rules[i].use[0] = {
loader: MiniCssExtractPlugin.loader,
};
//自动添加样式补全放
config.module.rules[i].use.splice(2, 0, 'postcss-loader');
}
//css样式合并
config.plugins.push(
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[chunkhash:8].css'),
})
)
}在 生产环境 下原来是用 ExtractTextPlugin 插件现在都改成了 MiniCssExtractPlugin
for循环里面主要是把 vue、css、less、scss 的第一个数组 style-loader 覆盖成 MiniCssExtractPlugin 否则会有冲突,
自动添加前缀的 postcss-loader 要放到最后面,这也是执行顺序的问题
在项目最外层要增加一个 postcss.config.js 内容是
module.exports = {
plugins: [
require('autoprefixer')({
browsers: ['last 20 versions']
})
]
}require的是一个自动补全css前缀的插件 last 20 versions 指的是兼容主流浏览器最近的20个版本,当然如果想要兼容到某个浏览器的特定版本也可以这样写
'last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie> 8
接下来是前面提过的 px转rem 和 eslint 语法检查,是否开启和关闭是在 config.js 里设置
build.js 是这里生产打包,操作都是先清空原来的输出目录,复制静态文件到输出目录 然后打包
const spinner = ora("开始构建生产环境.....");
spinner.start();
//清空