详细的配置可以参考官网:https://doc.webpack-china.org/guides/

一开始做项目时都是直接从组里前辈搭建好的脚手架开始写代码,到后来自己写新项目时又是拷贝之前的工程作为脚手架开始。对于脚手架本身却不甚了解,不仅不思考为什么更是没有改进的想法,怪不得工作满一年了却总觉得自己的技术水平在原地踏步,就是没有总结和思考。

目前组里的技术栈都是使用vue+koa,使用webpack的好处一是方便写vue的单文件组件,二是打包文件方便生产部署再加上能无所顾虑的应用语言的新特性。

1. 配置文件

官方文档推荐写webpack配置文件时,先写出一个基本配置文件(base)包含入口、输出等,再根据开发/生产环境所需要插件的不同,利用webpack-merge生成三个配置文件: dev、prod、analyze

package.json 依赖参考

"devDependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^7.1.1",
"babel-preset-es2015": "^6.18.0",
"css-loader": "^0.28.4",
"koa-webpack-dev-middleware": "^1.4.0",
"koa-webpack-hot-middleware": "^1.0.3",
"less": "^2.7.1",
"less-loader": "^4.0.5",
"style-loader": "^0.18.2",
"url-loader": "^0.5.7",
"vue-loader": "^12.2.2",
"webpack": "^3.3.0",
"webpack-bundle-analyzer": "^2.8.3",
"webpack-dev-middleware": "^1.11.0",
"webpack-dev-server": "^2.6.1",
"webpack-hot-middleware": "^2.13.1",
"webpack-koa-hot-middleware": "^0.1.2",
"webpack-manifest-plugin": "^1.2.1",
"webpack-merge": "^4.1.0"
}

webpack.config.base.js

 'use strict'
let path = require('path');
let webpack = require('webpack');
let WebpackManifestPlugin = require("webpack-manifest-plugin"); module.exports = {
output: {
path: path.resolve(__dirname, '..', 'build')
},
resolve: {
extensions: ['.js', '.vue'],
modules: ['node_modules'],
alias: {
'leafletCSS': 'leaflet/dist/leaflet.css',
'leaflet$': 'leaflet/dist/leaflet.js',
'vue$': 'vue/dist/vue.min.js',
'vue-resource$': 'vue-resource/dist/vue-resource.min.js'
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|jpe?g|gif|svg|woff2?|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
},
plugins: [
new WebpackManifestPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf('node_modules') !== -1;
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
chunks: ['qq', 'navi', 'log', 'guide', 'apply', 'voice', 'pianhang', 'dynamic'], //这里输入需要提取公共代码的entry
minChunks: 2
}),
//CommonChunksPlugin will now extract all the common modules from vendor and main bundles
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest', //But since there are no more common modules between them we end up with just the runtime code included in the manifest file
}),
]
}

第16行代码可以参考这里这里,默认NPM包导出的是运行时构建,Vue2的运行时构建不支持单文件组件的template

第58行的 WebpackManifestPlugin 作用是将输出文件名保存在文件中 (当输出文件名带 chunkhash 时很有用,参考这里)

第59~74行的 CommonsChunkPlugin 作用是从打包后的 bundle 文件中提取公共模块,将 npm install 的公共模块和业务代码分开,这样浏览器就可以一直缓存公共模块的bundle,参考这里。第一个 CommonsChunkPlugin 作用是将 node_modules 里的模块提取到 vendor.js 里;第二个 CommonsChunkPlugin 作用是将 entry 里的公共代码提取出来放在 common.js 里,参考这里;第三个 CommonsChunkPlugin 作用是将 webpack 运行时代码放在 manifest.js 里

webpack.config.dev.js

 "use strict"
let webpack = require('webpack');
let merge = require('webpack-merge');
let base_config = require('./webpack.config.base'); module.exports = merge(base_config, {
entry: {
qq: ['./src/qq/qq.js', 'webpack-hot-middleware/client'],
navi: ['./src/navi/navi.js', 'webpack-hot-middleware/client'],
log: ['./src/log/log.js', 'webpack-hot-middleware/client'],
guide: ['./src/guide/guide.js', 'webpack-hot-middleware/client'],
apply: ['./src/apply/apply.js', 'webpack-hot-middleware/client'],
voice: ['./src/voice/voice.js', 'webpack-hot-middleware/client'],
pianhang: ['./src/pianhang/pianhang.js', 'webpack-hot-middleware/client'],
dynamic: ['./src/dynamic/dynamic.js', 'webpack-hot-middleware/client']
},
output: {
filename: '[name].js',
},
devtool: '#eval-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(),
]
});

第 20 行设置source-map,方便用浏览器查看源代码

webpack.config.prod.js

 "use strict"
let webpack = require('webpack');
let merge = require('webpack-merge');
let base_config = require('./webpack.config.base'); module.exports = merge(base_config, {
entry: {
qq: ['./src/qq/qq.js'],
navi: ['./src/navi/navi.js'],
log: ['./src/log/log.js'],
guide: ['./src/guide/guide.js'],
apply: ['./src/apply/apply.js'],
voice: ['./src/voice/voice.js'],
pianhang: ['./src/pianhang/pianhang.js'],
dynamic: ['./src/dynamic/dynamic.js'],
},
output: {
filename: '[name].[chunkhash].js',
},
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
});

第 21 行 UglifyJsPlugin 的作用是压缩、混淆代码

webpack.config.analyze.js

 "use strict"

 let webpack = require('webpack');
let merge = require('webpack-merge');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
let prod_config = require('./webpack.config.prod'); module.exports = merge(prod_config, {
plugins: [
new BundleAnalyzerPlugin()
]
});

analyze 文件的作用利用 webpack-bundle-analyzer 插件分析打包情况,

webpack --config ./config/webpack.config.analyze.js

运行结果如下:

webpack的配置文件自定义程度很高,所以在参考他人配置时最好能弄清楚为什么要这样写

2. webpack-dev-server 

在开发过程中另一个重要的东西是 webpack-dev-server,它的作用是当你改动源代码后能自动重新打包,再加上 webpack 的HMR-模块热替换特性,这样改动代码就能直接在浏览器里看到效果,省却了代码手动打包+刷新浏览器的步骤。使用 webpack-dev-server 有 CLI 和 API 两种使用方法。

CLI 方式设置 dev 文件中的 HotModuleReplacementPlugin 和 devServer 启用 HMR。启动的命令为:

webpack-dev-server --config ./config/webpack.config.dev.js

API 方式直接在命令里设置参数,如:(这里用到了 Unix Domin Socket,也可以直接指定 ip和端口)

webpack-dev-server --config config/webpack.dev.config.js --public 0.0.0.0:8056 --progress --inline --hot --socket .dev-shared/sockets/webpack.sock

webpack-dev-server 的方式配置简单,缺点是引入 bundle 比较麻烦,需要指定其它端口

3. webpack-dev-middleware 

上述配置文件就是使用的该方法,需要有 koa-webpack-dev-middleware、koa-webpack-hot-middleware(热更新)。然后在 index.js 里写:

 if (process.env.NODE_ENV == 'dev') {
let webpack = require('webpack');
let webpackConfig = require('./config/webpack.config.dev.js');
let webpackDevMiddleware = require('koa-webpack-dev-middleware');
let webpackHotMiddleware = require('koa-webpack-hot-middleware');
let compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler));
app.use(webpackHotMiddleware(compiler));
}

这样就不需要通过额外的端口获取 bundle 文件了,注意这里是 koa 环境

4. 如何在前端框架里引入 bundle

由于 webpack prod 配置文件里使用了 chunkhash 作为 bundle 的名字的一部分,修改业务代码,chunkhash 会发生改变,所以需要通过一些方法自动将 bundle 名字注入到前端页面里:

第一种方法是通过在后端 controller 里读取 manifest.json 里的内容,然后通过模板引擎,注入到页面里,例如 nunjucks:

{% for path in paths %}
<script src="{{path}}"></script>
{% endfor %}

第二种方法是拓展模板引擎命令,例如 xtpl:

{{{ xScript('manifest.js') }}}
{{{ xScript('vendor.js') }}}
{{{ xScript('common.js') }}}
{{{ xScript('apply.js') }}}

xtpl 命令拓展示例 xtpl.ext.js :

 let xtplApp = require('xtpl/lib/koa');
let xtpl = require('xtpl/lib/xtpl');
let XTemplate = xtpl.XTemplate; XTemplate.addCommand('xScript', function(scope, option){
let name = option.params[0];
if (process.env.NODE_ENV !== 'dev') {
let assets_map = require('./manifest');
name = assets_map[name];
}
return '<script src="' + name + '" ></script>';
}); module.exports = xtplApp;

然后在 index.js 里

let xtpl = require('./extensions/xtpl.ext');

注意引入 bundle 的时候要注意引入顺序:manifest > vendor > common > entry,否则可能会报 ReferenceError: webpackJsonp is not defined 错误,还要注意要有 .babelrc 文件:

{
"presets": ["es2015"]
}

否则会报 SyntaxError: Unexpected token: name (xxxxxx) from Uglify plugin 之类的错误,无法识别语言新特性

webpack2配置的更多相关文章

  1. webpack2配置备份

    package.json: { "name": "leyi", "version": "1.0.0", "ma ...

  2. webpack2 配置 示例

    // https://github.com/webpack-contrib/extract-text-webpack-plugin var webpack = require("webpac ...

  3. webpack2的配置属性说明entry,output,state,plugins,node,module,context

    Webpack2配置属性详解 webpack说明 webpack是前端构建的一个核心所在,如果说后端构建就是把高级语言代码编译成机器码,那么前端的构建就是重新组合原有的代码,虽然并不编译成机器码,但实 ...

  4. eslint webpack2 vue-loader配置

    eslint是一个代码检测工具 官网如下http://eslint.cn/ npm install eslint --save-dev 需要这几个npm包: eslint eslint-loader ...

  5. 一步步构造自己的vue2.0+webpack环境

    前面vue2.0和webpack都已经有接触了些(vue.js入门,webpack入门之简单例子跑起来),现在开始学习如何构造自己的vue2.0+webpack环境. 1.首先新建一个目录vue-wk ...

  6. SpringBoot vue

    springboot 整合vue就行前后端完全分离,监听器,过滤器,拦截器 https://github.com/ninuxGithub/spring-boot-vue-separateA blog ...

  7. webpack2.0配置postcss-loader

    使用webpack2.0配置postcssloader 安装postcss-loader npm install --save-dev postcss-loader 然后配置webpack.confi ...

  8. Webpack 2 视频教程 011 - Webpack2 中加载 CSS 的相关配置与实战

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  9. 通过webpack2从0开始配置自己的vue项目 1

    PS 阅读者需要node基础.webpack原理知识.vue基础 安装node 这个网上很多教程 打开终端 创建项目 npm init 全局安装: cnpm i webpack webpack-dev ...

随机推荐

  1. PHP memcache的使用教程

    (结尾附:完整版资源下载) 首先,为什么要用memcached?如果你看过InnoDB的一些书籍,你应该知道在存储引擎那一层是由一个内存池的.而在内存池中 又有一个缓冲池.而缓冲池就会缓冲查找的数据, ...

  2. SQL CHECK sql server免费监控单实例工具

    SQL Check 阅读目录 SQL Check? 主要特点 说说不足 下载地址 小结 一款实时性能监测工具 回到目录 SQL Check? 一款实时监测SQL数据库性能.实时排查的问题的免费工具. ...

  3. AngularJS 笔记之创建服务方式比较 : factory vs service vs provider 。

    首先说一下服务这个东西是用来干嘛的.很多时候我们把太多的数据和逻辑都一股脑儿地往 controller 里放.这样我们的 controller 原来越臃肿.从它们的生命周期可以发现,其实 contro ...

  4. String与其他类型的转换

    首先,对于String类有一点是毫无疑问的:对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象. 一. String与StringBuilder.StringBu ...

  5. Java并发之——线程池

    一. 线程池介绍 1.1 简介 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡 ...

  6. webdeploy启用备份 msdeploy 启用backup

    前提准备:完整安装Microsoft Web Deploy 3 下载页面:WebDeploy_amd64_zh-CN.msi msdeploy 同步站点 命令所在目录C:\Program Files\ ...

  7. Spring框架学习之IOC(一)

    Spring框架学习之IOC(一) 先前粗浅地学过Spring框架,但当时忙于考试及后期实习未将其记录,于是趁着最近还有几天的空闲时间,将其稍微整理一下,以备后期查看. Spring相关知识 spri ...

  8. 【工具】PC端调试手机端 Html 页面的工具

    一.概述 有一个项目需要在手机端显示一个 web 页面,而每次把应用 launch 后,从手机端看比较麻烦,因此搜罗了几种在 PC 端调试手机端页面的工具. 二.工具 http://fonkie.it ...

  9. HDOJ 2203 亲和串 【KMP】

    HDOJ 2203 亲和串 [KMP] Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  10. caffe训练自己的数据集

    默认caffe已经编译好了,并且编译好了pycaffe 1 数据准备 首先准备训练和测试数据集,这里准备两类数据,分别放在文件夹0和文件夹1中(之所以使用0和1命名数据类别,是因为方便标注数据类别,直 ...