1.webpack是什么?
2.为何要用webpack?
3.怎么用webpack?css
webpack是什么?
html
答:webpack是前端模块化应用和开发的打包工具,解决前端模块依赖的工具。打包全部的脚本,图片,css。前端
为何要用webpack?
答:使用webpack能够让前端开发变得工程化和模块化,方便前端开发,提升开发速率。
webpack的主要优势是:模块化。
缺点是配置繁琐。vue
怎么使用webpack?
答:参考官网文档:https://webpack.js.org/concepts/
或者中文文档:https://www.webpackjs.com/concepts/
看完后还不知道怎么用?请看个人使用例子。node
本例中使用webpack的目的:
1.前端开发独立于后端使用webpack-dev-server,将页面可在本地查看,webpack-dev-server中的proxy,代理后端借口
2.用webpack的loader解析.vue后缀的文件
3.配置webpack的热更新,使得修改前端代码,页面自动更新
4.利用webpack-merge区分开发环境的配置和生产环境的配置
5.自动解析生产页面jquery
webpack依赖webpack.config文件,生产环境和开发环境对应不用的位置文件,共同的配置文件放在一块儿
webpack
src 目录
web
package.json文件中的配置npm
"scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --config ./webpack_config/webpack.config.development.js", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules --config ./webpack_config/webpack.config.production.js" },
webpack.config.common.js中的配置json
var path = require('path') var webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const ManifestPlugin = require('webpack-manifest-plugin'); var glob = require('glob') var files = glob.sync(path.resolve(__dirname, '../src/*/index.js')); var newEntries = {}; const config = { entry: { vendor: [ './public/bower_components/jquery/dist/jquery.js', './public/bower_components/bootstrap/dist/css/bootstrap.css', './public/bower_components/bootstrap/dist/js/bootstrap.js' ] }, output: { path: path.resolve(__dirname, '../public/vue_dist/'), publicPath: '/vue_dist/', filename: '[name].js' }, module: { rules: [{ test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], }, { test: /\.scss$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader' ], }, { test: /\.sass$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ], }, { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { // Since sass-loader (weirdly) has SCSS as its default parse mode, we map // the "scss" and "sass" values for the lang attribute to the right configs here. // other preprocessors should work out of the box, no loader config like this necessary. 'scss': [ 'vue-style-loader', 'css-loader', 'sass-loader' ], 'sass': [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ] } // other vue-loader options go here } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/, use: [{ loader: 'url-loader', options: { limit: 10000 } }] }, { test: path.resolve(__dirname, '../public/bower_components/jquery/dist/jquery.js'), use: [{ loader: 'expose-loader', options: 'jQuery' }, { loader: 'expose-loader', options: '$' }] } ] }, plugins: [ new ManifestPlugin() ], resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' }, extensions: ['*', '.js', '.vue', '.json'] }, performance: { hints: false } } console.log(files + '------------files-------------------------'); files.forEach(function(f) { var name = /.*\/(.*?\/index)\.js/.exec(f)[1]; //register/main这样的文件名 console.log(name + '------------name-------------------------'); newEntries[name] = f; }); console.log(newEntries + '------------newEntries-------------------------'); config.entry = Object.assign({}, config.entry, newEntries); module.exports = config;
webpack.config.development.js 配置文件
const merge = require('webpack-merge'); const common = require('./webpack.config.common.js'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') const webpack = require('webpack') var glob = require('glob') var files = glob.sync(path.resolve(__dirname, '../src/*/index.js')); var plugins = []; files.forEach(function(f) { var name = /.*\/(.*?\/index)\.js/.exec(f)[1]; //register/main这样的文件名 var plug = new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../public/vue_dist/' + name + '.html'), chunks: ['vendor', name], template: path.resolve(__dirname, '../src/index.html'), inject: true }); plugins.push(plug); }); plugins.push( new webpack.optimize.CommonsChunkPlugin({ names: ['vendor'] })); module.exports = merge(common, { plugins: plugins, devtool: '#eval-source-map', devServer: { historyApiFallback: true, noInfo: true, overlay: true, port: 8080, host: 'localhost', publicPath:'/vue_dist', proxy: [{ context: ["/upload", "/phone",'/register','/users'], target: "http://127.0.0.1:3000", }], openPage: 'vue_dist/upload/index.html' }, output: { path: path.resolve(__dirname, '../public/vue_dist/'), publicPath: '/vue_dist', filename: '[name].js' }, });
webpack.config.production.js 配置文件
const merge = require('webpack-merge'); const common = require('./webpack.config.common.js'); const path = require('path'); var webpack = require('webpack') const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin') var fillter = ['upload'] var glob = require('glob') var files = glob.sync(path.resolve(__dirname, '../src/*/index.js')); var plugins = []; files.forEach(function(f) { var name = /.*\/(.*?\/index)\.js/.exec(f)[1]; //register/main这样的文件名 var c = false; for (let f = 0; f < fillter.length; f++) { const element = fillter[f]; if (name.indexOf(element) > -1) { c = true; break; } } if (!c) { var plug = new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../public/vue_dist/' + name + '.html'), chunks: [name], template: path.resolve(__dirname, '../src/index.html'), inject: true }); plugins.push(plug); } }); plugins.push( new CleanWebpackPlugin(['vue_dist'], { // Absolute path to your webpack root folder (paths appended to this) // Default: root of your package root: path.resolve(__dirname, '../public/'), // Write logs to console. verbose: true, // Use boolean "true" to test/emulate delete. (will not remove files). // Default: false - remove files dry: false, // If true, remove files on recompile. // Default: false watch: false, // Instead of removing whole path recursively, // remove all path's content with exclusion of provided immediate children. // Good for not removing shared files from build directories. exclude: ['files', 'to', 'ignore'], // allow the plugin to clean folders outside of the webpack root. // Default: false - don't allow clean folder outside of the webpack root allowExternal: false, // perform clean just before files are emitted to the output dir // Default: false beforeEmit: false }) ) module.exports = merge(common, { devtool: '#eval-source-map', plugins: plugins }); if (process.env.NODE_ENV === 'production') { module.exports.devtool = '#source-map' // http://vue-loader.vuejs.org/en/workflow/production.html module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false } }), new webpack.LoaderOptionsPlugin({ minimize: true }) ]) }
用到的插件:
CleanWebpackPlugin 删除目录专用
HtmlWebpackPlugin Plugin that simplifies creation of HTML files to serve your bundles
webpack-merge 合并webpack.config 文件
glob 找到匹配的文件
ManifestPlugin Webpack plugin for generating asset manifests. 生成打包列表like this
{
"register/index.js": "/vue_dist/register/index.js",
"register/index.js.map": "/vue_dist/register/index.js.map",
"upload/index.js": "/vue_dist/upload/index.js",
"upload/index.js.map": "/vue_dist/upload/index.js.map",
"vendor.js": "/vue_dist/vendor.js",
"vendor.js.map": "/vue_dist/vendor.js.map",
"element-icons.ttf": "/vue_dist/6f0a76321d30f3c8120915e57f7bd77e.ttf",
"glyphicons-halflings-regular.woff2": "/vue_dist/448c34a56d699c29117adc64c43affeb.woff2",
"glyphicons-halflings-regular.woff": "/vue_dist/fa2772327f55d8198301fdb8bcfc8158.woff",
"glyphicons-halflings-regular.ttf": "/vue_dist/e18bbf611f2a2e43afc071aa2f4e1512.ttf",
"glyphicons-halflings-regular.svg": "/vue_dist/89889688147bd7575d6327160d64e760.svg",
"glyphicons-halflings-regular.eot": "/vue_dist/f4769f9bdb7466be65088239c12046d1.eot"
}
expose-loader 解决全局变量的问题 like jQuery 和 $ 对应
webpack 配置总结
webpack配置目的,自动打包,热加载,快速开发,将须要的部分配置好自动打包
打包策略
首先,项目打包策略遵循如下几点原则:
选择合适的打包粒度,生成的单文件大小不要超过500KB
充分利用浏览器的并发请求,同时保证并发数不超过6
尽量让浏览器命中304,频繁改动的业务代码不要与公共代码打包
避免加载太多用不到的代码,层级较深的页面进行异步加载
基于以上原则,我选择的打包策略以下:
第三方库如vue、jquery、bootstrap打包为一个文件
公共组件如弹窗、菜单等打包为一个文件
工具类、项目通用基类打包为一个文件
各个功能模块打包出本身的入口文件
各功能模块做用一个SPA,子页面进行异步加载
webpack配置
entry 入口文件,多入口。apps/question/index这样的,则会生成对应的目录结构
output 打包后的出口文件
plugin 插件
rules 文件处理
devserver 开发服务器,可代理接口,方便与后台开发
.....
0.约定开发目录结构
1.多入口,多出口,按须要的文件夹生成打包后的文件 glob
2.生产环境和开发环境分开配置,webpack-merg
若有错漏,请多多指教!