不想看下面废话的,能够直接看这里。css
这两周负责公司前端基础工程的建设。主要作了两套方案,一套是基于vue的单页应用,还有一套就是多页应用。对于vue单页这块是没什么问题的,直接用vue-cli生成项目,再怼上vue全家桶以及一些工具函数,而后规范一下目录结构啥的基本就ok了。html
麻烦的是原先使用 gulp+require.js 这个方案。这个在我来公司以前就已经存在,当初我刚来的时候使用的是 grunt+require.js+jQuery(zepto)+sass ,而后我用这个第一次写项目时,实在受不了了 grunt 的缓慢,就换成了 gulp 。此次对于这个方案我原本也只是想小改一下,由于这个方案用着还行,我就想加个 ES6 把 require.js 干掉,而后还有些其余小问题的修复就行了。前端
而后按照想法开始给 gulp 任务里加上 babel 处理 ES6 。而后运行,发现若是使用了ES6中的 module,经过 import
、export
进行模块化开发,那么经过babel转码后,import
、export
会被转成符合CMD规范的 require
和 exports
等,可是浏览器仍是跑不了,这时还须要 bowserify 、webpack 、rollup 之类的对代码再次进行构建。这太麻烦了,还不如使用 webpack 一步到位。嗯仍是不能偷懒啊。vue
├── build # webpack处理目录 │ ├── build.js │ ├── config.js │ ├── run-env.js │ ├── utils.js │ ├── webpack.config.base.js │ ├── webpack.config.dev.js │ └── webpack.config.prod.js ├── dist # 打包以后的文件目录 │ ├── commons.bundle.js │ ├── css │ │ ├── index.eb8584e93d4fbcbec235.css │ │ └── test.eb8584e93d4fbcbec235.css │ ├── img │ │ └── test.d7a9b40f5bed4003db2585ba1bf24d86.jpg │ ├── index.html │ ├── js │ │ ├── index.bundle.eb8584e93d4fbcbec235.js │ │ └── test.bundle.eb8584e93d4fbcbec235.js │ └── test.html ├── src # 源文件 │ ├── css │ │ ├── base.scss │ │ ├── index.scss │ │ ├── test.scss │ │ └── var.scss │ ├── html │ │ ├── index.html │ │ └── test.html │ ├── img │ │ └── test.jpg │ └── js │ ├── app │ │ ├── index.js │ │ └── test.js │ ├── base │ └── component ├── webpack.config.js # webpack入口
先看下package.json
里的命令和依赖node
script:android
"scripts": { "init-page": "node ./init-page.js", "dev": "export NODE_ENV=development && webpack-dev-server --open", "build": "export NODE_ENV=production && node ./build/build.js" }
依赖:webpack
"devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.0", "clean-webpack-plugin": "^0.1.17", "css-loader": "^0.28.7", "eslint": "^4.10.0", "eslint-config-standard": "^10.2.1", "eslint-plugin-html": "^3.2.2", "eslint-plugin-import": "^2.8.0", "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.6.0", "eslint-plugin-standard": "^3.0.1", "exports-loader": "^0.6.4", "extract-text-webpack-plugin": "^3.0.1", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "html-withimg-loader": "^0.1.16", "node-sass": "^4.5.3", "postcss-loader": "^2.0.7", "preprocess-loader": "^0.2.2", "sass-loader": "^6.0.6", "script-loader": "^0.7.2", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.7.1", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }
webpack的入口文件是 webpack.config.js
,在这个文件中就是根据命令执行相应的 webpack 配置:ios
const env = process.env.NODE_ENV === 'production' ? 'prod' : 'dev'; // 根据环境执行指定文件 module.exports = require(`./build/webpack.config.${env}.js`);
在webpack.base.config.js
中就是webpack的一些常规处理包括loader以及一些文件清理啥的。因为要配置的是多页应用因此对于入口文件的处理,这也是比较麻烦的一点。对于多入口文件的处理使用html-webpack-plugin
这个插件。
在使用以前须要先获取全部的html文件名称,这个我是使用 node 的 fs
以及 path
api 来获取的:git
/*获取html文件名*/ module.exports = { getFileNameList(path) { let fileList = []; let dirList = fs.readdirSync(path); dirList.forEach(item => { if (item.indexOf('html') > -1) { fileList.push(item.split('.')[0]); } }); return fileList; } };
而后再处理webpack入口以及 html plugin:github
// 入口html数组 let HTMLDirs = utils.getFileNameList('./src/html'); let HTMLPlugins = []; // 入口文件集合处理 let entries = {}; HTMLDirs.forEach(page => { const htmlPlugin = new HTMLWebpackPlugin({ filename: `${page}.html`, template: path.resolve(__dirname, `../src/html/${page}.html`), chunks: [page, 'commons'] }); HTMLPlugins.push(htmlPlugin); entries[page] = path.resolve(__dirname, `../src/js/app/${page}.js`); });
相关webpack配置,具体配置见github
// webpack配置 module.exports = { entry: entries, ... plugins: [ // 自动生成 HTML 插件 ...HTMLPlugins ] };
最复杂的麻烦的都在base中干完了,本地开发和打包build只要作一些简单的处理就ok了
本地与线上的配置文件,须要先合并 base 里的配置(使用 webpack-merge 能够处理这个工做),而后作一下简单处理便可。
// dev module.exports = webpackMerge(webpackBase, { devServer: { contentBase: config.devServerOutputPath, overlay: { errors: true, warnings: true } } });
// prod module.exports = webpackMerge(webpackBase, { devtool: false, plugins: [ // 代码压缩 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }), // 提取公共 JavaScript 代码 new webpack.optimize.CommonsChunkPlugin({ // chunk 名为 commons name: 'commons', filename: '[name].bundle.js' }) ] });
在处理zepto之类的未模块化的库的时候我采起的方案是cdn加载,而后webpack配置里加上外部扩展便可
(externals 能够防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies))
externals: { 'zepto': '$' }
以前这套方案是要作三端的H5以及嵌入android、ios的webview,因此须要根据平台作一些特殊处理。gulp里有gulp-preprocess
能够比较好的处理,在webpack中可使用 preprocess-loader
来处理。
{ test: /\.(html|js|css|scss)$/, loader: `preprocess-loader?${runEnv}` }
暂时只作了这些,这套工具尚未正式投入使用估计会有挺多问题的。后续有问题会继续补充
感谢您的阅读,本文由赵的拇指版权全部。原文地址: https://www.zhaofinger.com/detail/11