不想看下面廢話的橱夭,可以直接看這里。
前言
這兩周負(fù)責(zé)公司前端基礎(chǔ)工程的建設(shè)工扎。主要做了兩套方案徘钥,一套是基于vue的單頁應(yīng)用,還有一套就是多頁應(yīng)用肢娘。對于vue單頁這塊是沒什么問題的呈础,直接用vue-cli生成項目,再懟上vue全家桶以及一些工具函數(shù)橱健,然后規(guī)范一下目錄結(jié)構(gòu)啥的基本就ok了而钞。
麻煩的是原先使用 gulp+require.js 這個方案。這個在我來公司之前就已經(jīng)存在拘荡,當(dāng)初我剛來的時候使用的是 grunt+require.js+jQuery(zepto)+sass 臼节,然后我用這個第一次寫項目時,實在受不了了 grunt 的緩慢珊皿,就換成了 gulp 网缝。這次對于這個方案我本來也只是想小改一下,因為這個方案用著還行蟋定,我就想加個 ES6 把 require.js 干掉粉臊,然后還有些其他小問題的修復(fù)就好了。
然后按照想法開始給 gulp 任務(wù)里加上 babel 處理 ES6 驶兜。然后運行扼仲,發(fā)現(xiàn)如果使用了ES6中的 module,通過 import
抄淑、export
進(jìn)行模塊化開發(fā)屠凶,那么通過babel轉(zhuǎn)碼后,import
肆资、export
會被轉(zhuǎn)成符合CMD規(guī)范的 require
和 exports
等矗愧,但是瀏覽器還是跑不了,這時還需要 bowserify 迅耘、webpack 贱枣、rollup 之類的對代碼再次進(jìn)行構(gòu)建监署。這太麻煩了颤专,還不如使用 webpack 一步到位纽哥。嗯還是不能偷懶啊。
項目結(jié)構(gòu)
├── 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
先看下package.json
里的命令和依賴
script:
"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"
}
依賴:
"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的入口文件是 webpack.config.js
栖秕,在這個文件中就是根據(jù)命令執(zhí)行相應(yīng)的 webpack 配置:
const env = process.env.NODE_ENV === 'production' ? 'prod' : 'dev';
// 根據(jù)環(huán)境執(zhí)行指定文件
module.exports = require(`./build/webpack.config.${env}.js`);
webpack 基礎(chǔ)配置
在webpack.base.config.js
中就是webpack的一些常規(guī)處理包括loader以及一些文件清理啥的春塌。由于要配置的是多頁應(yīng)用所以對于入口文件的處理,這也是比較麻煩的一點簇捍。對于多入口文件的處理使用html-webpack-plugin
這個插件只壳。
在使用之前需要先獲取所有的html文件名稱,這個我是使用 node 的 fs
以及 path
api 來獲取的:
/*獲取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:
// 入口html數(shù)組
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`);
});
相關(guān)webpack配置暑塑,具體配置見github
// webpack配置
module.exports = {
entry: entries,
...
plugins: [
// 自動生成 HTML 插件
...HTMLPlugins
]
};
最復(fù)雜的麻煩的都在base中干完了吼句,本地開發(fā)和打包build只要做一些簡單的處理就ok了
webpack 本地開發(fā)文件配置與打包線上文件配置
本地與線上的配置文件,需要先合并 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 等未模塊化的庫的處理
在處理zepto之類的未模塊化的庫的時候我采取的方案是cdn加載,然后webpack配置里加上外部擴(kuò)展即可
(externals 可以防止將某些 import 的包(package)打包到 bundle 中驹愚,而是在運行時(runtime)再去從外部獲取這些擴(kuò)展依賴(external dependencies))
externals: {
'zepto': '$'
}
preprocess
之前這套方案是要做三端的H5以及嵌入android远搪、ios的webview,所以需要根據(jù)平臺做一些特殊處理逢捺。gulp里有gulp-preprocess
可以比較好的處理谁鳍,在webpack中可以使用 preprocess-loader
來處理。
{
test: /\.(html|js|css|scss)$/,
loader: `preprocess-loader?${runEnv}`
}
后記
暫時只做了這些劫瞳,這套工具還沒有正式投入使用估計會有挺多問題的倘潜。后續(xù)有問題會繼續(xù)補充。
感謝您的閱讀志于,本文由 趙的拇指 版權(quán)所有涮因。原文地址: https://www.zhaofinger.com/detail/11