详细的配置可以参考官网: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. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  2. shell脚本调用传参【转载】

    转自:https://www.cnblogs.com/cisum/p/8010658.html 1.直接使用$0,$1,$2,$3 $0是脚本的名字,就是按顺序来 #!/bin/bash # auth ...

  3. 使用pycharm操作django

    新建项目,选择已经建立好的虚拟环境 进入指令界面 新建app 添加一些文件和文件夹用于以后存放各种数据 settings设置 TEMPLATES设置 TEMPLATES = [ { 'BACKEND' ...

  4. Centos学习笔记1-基本部分

    1:查看系统的使用状态: 谁在线:who 网络连接状态:netstat  –a 后台执行程序:ps –aux 2:关机 关机:shutdown   或者 shutdown –h now 重启:rebo ...

  5. SqlServer分页总结-摘抄

    sqlserver2008不支持关键字limit ,所以它的分页sql查询语句将不能用mysql的方式进行,幸好sqlserver2008提供了top,rownumber等关键字,这样就能通过这几个关 ...

  6. 09 Spring框架 AOP (二) 高级用法

    上一篇文章我们主要讲了一点关于AOP编程,它的动态考虑程序的运行过程,和Spring中AOP的应用,前置通知,后置通知,环绕通知和异常通知,这些都是Spring中AOP最简单的用法,也是最常用的东西, ...

  7. Linux常用命令(6/26)——dd命令和split命令

    dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 以可选块长度复制文件,默认情况下从标准输入设备输出到标准输出设备.复制过程中,还可以对文件进行一些转换. dd命令可以指定block的 ...

  8. BeatSaber节奏光剑插件开发官方教程1-创建一个插件模板

    原文:https://wiki.assistant.moe/modding/intro 一.简介 Beat Saber 开发环境:unity2018.C#..NET framework 4.6. 此教 ...

  9. 利用Metasploit进行Linux提权

    利用Metasploit进行Linux提权 Metasploit 拥有msfpayload 和msfencode 这两个工具,这两个工具不但可以生成exe 型后门,一可以生成网页脚本类型的webshe ...

  10. 2.scala控制结构、函数、异常处理

    2.scala控制结构.函数.异常处理---小书匠,在线编辑器,MARKDOWN,Evernote,文件版本 a:focus { outline: thin dotted #333; outline: ...