webpack把任何一个文件都当作是一个模块,模块间能够相互依赖(require or import),webpack的功能就是把相互依赖的文件打包在一块儿。webpack自己只能处理原生的Javascript模块,可是它支持的各类loader转换器能够将各类类型的资源转换成javascript模块。这样任何资源均可以成为webpack能够处理的模块。同时,webpack还有丰富的插件plugin, 能够完成例如js,css的压缩,公共依赖模块的提取和注入,甚至利用模板对html进行动态拼接等功能。同时,webpack使用commonjs规范(require),支持es6语法(import)的编译。官方网站:https://doc.webpack-china.org/javascript
深刻浅出webpack系列教程:http://www.cnblogs.com/ghostwu/p/7499237.htmlcss
npm install webpack -g //全局安装html
npm install webpack --save-dev //开发环境java
在package.json文件同级目录中建立一个webpack.config.js文件,这个文件是webpack的配置文件。node
const webpack = require('webpack'); const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //页面入口文件配置 entry: { polyfills: './src/main/webapp/app/polyfills', global: './src/main/webapp/content/scss/global.scss', main: './src/main/webapp/app/app.main' }, //入口文件输出配置 output: { path: utils.root('build/www'), filename: 'app/[name].bundle.js', chunkFilename: 'app/[id].chunk.js' }, module: { //加载器配置 loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.js$/, loader: 'jsx-loader?harmony' }, { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, //图片文件使用 url-loader 来处理,小于8kb的直接转为base64 { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }, //解析模块路径时的配置 resolve: { root: 'E:/github/flux-example/src', //绝对路径,查找module的话从这里开始查找 extensions: ['', '.js', '.json', '.scss'], //自动扩展文件后缀名,意味着咱们require模块能够省略不写后缀名 alias: { //别名配置,,方便后续直接引用别名,无须多写长长的地址 AppStore : 'js/stores/AppStores.js', ////后续直接 require('AppStore') 便可 ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' } }, //插件项 plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', chunks: ['main'], minChunks: (module) => utils.isExternalLib(module) }), new BrowserSyncPlugin({ host: 'localhost', port: 9000, proxy: { target: 'http://localhost:9060', ws: true } }, { reload: false }), new HtmlWebpackPlugin({ template: './src/main/webapp/index.html', chunksSortMode: 'dependency', inject: 'body' }) ], };
devtool: 'eval-source-map' //webpack
就能够在打包时为咱们生成的source maps
,这为咱们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试react
在webpack
的配置文件中配置source maps
,须要配置devtool
,它有如下四种不一样的配置选项,各具优缺点,描述以下:jquery
devtool选项 | 配置结果 |
---|---|
source-map |
在一个单独的文件中产生一个完整且功能彻底的文件。这个文件具备最好的source map ,可是它会减慢打包速度; |
cheap-module-source-map |
在一个单独的文件中生成一个不带列映射的map ,不带列映射提升了打包速度,可是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试形成不便; |
eval-source-map |
使用eval 打包源文件模块,在同一个文件中生成干净的完整的source map 。这个选项能够在不影响构建速度的前提下生成完整的sourcemap ,可是对打包后输出的JS文件的执行具备性能和安全的隐患。在开发阶段这是一个很是好的选项,在生产阶段则必定不要启用这个选项; |
cheap-module-eval-source-map |
这是在打包文件时最快的生成source map 的方法,生成的Source Map 会和打包后的JavaScript 文件同行显示,没有列映射,和eval-source-map 选项具备类似的缺点; |
正如上表所述,上述选项由上到下打包速度愈来愈快,不过同时也具备愈来愈多的负面做用,较快的打包速度的后果就是对打包后的文件的的执行有必定影响。webpack
对小到中型的项目中,eval-source-map
是一个很好的选项,再次强调你只应该开发阶段使用它。git
cheap-module-eval-source-map
方法构建速度更快,可是不利于调试,推荐在大型项目考虑时间成本时使用。es6
devServer: { //设置 webpack-dev-server 的相关配置,devServer的更多配置信息参考https://webpack.js.org/configuration/dev-server/
contentBase: './build/www', //本地服务器所加载的页面所在的目录
proxy: [{
context: [],
target: 'http://127.0.0.1:8080',
secure: false,
ws: true/false
}],
historyApiFallback: true,//不跳转
inline: true, //实时刷新
hot: true
},
devserver的配置选项 | 功能描述 |
---|---|
contentBase | 默认webpack-dev-server会为根文件夹提供本地服务器,若是想为另一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到“public"目录) |
port | 设置默认监听端口,若是省略,默认为”8080“ |
inline | 设置为true ,当源文件改变时会自动刷新页面 |
historyApiFallback | 在开发单页应用时很是有用,它依赖于HTML5 history API,若是设置为true ,全部的跳转将指向index.html |
entry: {}
output: {
path: '',
filename: '',
publicPath: '',
chunkFilename: ''
},
resolve: {
alias: [], //设置模块别名
root: '', //包含你模块的目录(必须是绝对路径),一般是一个目录数组,这个设置应该被用于添加我的目录到webpack查找路径里.
modulesDirectories:[], //解析目录名的一个数组到当前目录以及先前的目录,而且是查找模块。这个函数和node怎么找到node_modules很像。好比若是值为 // // ["mydir"],webpack会查找“./mydir”, “../mydir”, “../../mydir”,等等。默认: ["web_modules", "node_modules"]
extensions: [] //解析模块的拓展名的数组。设置这个选项将会重写默认值,这意味着webpack再也不试着用默认的拓展名解析模块,若是你但愿模块加载的时候带着他们的拓展名也能够获得正确额解析(好比require('./somefile.ext')),你须要在你的数组里添加一个空字符串。若是你但愿模块加载不带拓展名(好比require('underscore'))能够解析为“.js”的拓展名。你必须在数组里包含".js".
},
externals: [], // 指定的依赖不会被webpack解析,但会成为bundle里的依赖。output.libraryTarget.决定着依赖的类型。值是对象,字符串,函数,正则,数组都会被接受。
stats: {}
module: {
rules(或loaders): [
{
test: string, //必须知足的条件,正则表达式(测试绝对路径),包含绝对路径的字符串
enforce: string,
loaders: ['','',...] , //多个loader
loader: string, //用“!”隔开多个loader
exclude: ['','',...], //不知足的条件
include: ['','',...] //必须知足条件
},
{ test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ },
{
test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader",
options: { modules: true }
},
{ loader: "postcss-loader" }
] }options: { modules: true }{ loader: "postcss-loader" }
],
preLoaders: [],
postLoaders: [],
noParse: []
},
Loaders须要单独安装而且须要在webpack.config.js
中的modules
关键字下进行配置,Loaders的配置包括如下几方面:
test
:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)loader
:loader的名称(必须)include/exclude
:手动添加必须处理的文件(文件夹)或屏蔽不须要处理的文件(文件夹)(可选);query
:为loaders提供额外的设置选项(可选)plugins: []
$ webpack --config XXX.js //使用另外一份配置文件(好比webpack.config2.js)来打包 $ webpack --watch //监听文件是否有改变,有改变就会从新编译有改变的文件 $ webpack -p//压缩混淆脚本 $ webpack -d//生成map映射文件,告知哪些模块被最终打包到哪里了 $ webpack --progress //显示打包过程进度条 $ webpack --color //配置打包输出颜色显示
NoErrorsPlugin插件:该插件能够在webpack打包过程当中遇到错误时跳过,不终止webpack进程~
PrefetchPlugin插件:该插件的做用是当一个模块还未被require以前,提早解析和创建一个对该插件的请求,能够起到必定的优化打包时间的效果。其中两个参数第一个是模块的绝对路径,第二个是对模块的请求字符串,eg.
new webpack.PrefetchPlugin(__dirname +”/node_modules”,”react/react.js”)
HotModuleReplacementPlugin插件:热更新所需插件,实现模块变更部分的替代而不从新刷新页面,有效提升调试时间
HtmlWebpackPlugin插件:能够为你生成一个自动引用你打包后的JS文件的新index.html
BrowserSyncPlugin
插件:它当你的webpack或webpack-dev-server 执行彻底后,自动为你的应用打开浏览器~
new BrowserSyncPlugin({ host: 'localhost', port: 9000, // 代理服务器配置 proxy: { target: 'http://localhost:9060', ws: true } }, { reload: false })
Webpack.DefinePlugin插件: 能够定义编译时的全局变量,有不少库(React, Vue等)会根据 NODE_ENV 这个变量来判断当前环境。为了尽量减小包大小,在生产环境中要定义其为 JSON.stringify(“production”)
plugins: [ new webpack.DefinePlugin({ "process.env.NODE_ENV": "development" }) ]
Webpack.optimize.CommonsChunkPlugin插件:它用于提取多个入口文件的公共脚本部分,而后生成一个 common.js 来方便多页面之间进行复用
具体使用方法见http://www.jianshu.com/p/2b81262898a4
Webpack.ContextReplacementPlugin插件:
Webpack.ProvidePlugin插件:定义一些在import时能自动引入的变量,如定义了 $: 'jquery'
后,能够在文件中直接使用$
,webpack能够自动帮你加上 var $ = require('jquery')
。
Webpack.LoaderOptionsPlugin插件
Webpack.NoEmitOnErrorsPlugin插件:
Webpack.NamedModulesPlugin插件
Webpack.WatchIgnorePlugin插件:
FaviconsWebpackPlugin插件:该插件则能够为不一样的设备自动生成超过30种的favicon(它们的来源都是同一张图片)
CopyWebpackPlugin插件:
MergeJsonWebpackPlugin插件:
StringReplacePlugin插件:
WebpackNotifierPlugin插件:
writeFilePlugin插件:
ExtractTextPlugin: 分离CSS和JS文件。
new ExtractTextPlugin("style.css")
DedupePlugin插件:可在production环境下帮助删除重复或类似文件,能够有效减小文件大小(用于打包文件优化,建议使用在生产环境)
OccurrenceOrderPlugin插件:根据出现次数为每个模块或者chunk设置id,常用的模块则会获取到较短的id(和前缀树相似),这可使id可预测并有效减小文件大小,建议使用在生产环境中~
NpmInstallPlugin插件:这个并未在webpack官网的插件列表内提到过,可是我的认为它经过自动帮助咱们安装依赖而提高了咱们的开发效率,https://github.com/ericclemmons/npm-install-webpack-plugin,具体效果能够看下官网~
plugins: [ new NpmInstallPlugin({ // Use --save or --save-dev dev: false, // Install missing peerDependencies peerDependencies: true, }); ],
webpack.optimize.UglifyJsPlugin插件: 压缩js
new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, // Drop `console` statements drop_console: true } })
webpack-merge: 能够把分开配置的config合并,分开生产环境和调试环境
const merge = require('webpack-merge'); const commonConfig= {}; module.exports = merge(commonConfig, {});
webpack-validator: 验证咱们的config是否正确
const merge = require('webpack-merge'); const validate = require('webpack-validator'); const commonConfig = {}; const config = merge(commonConfig, {}); module.exports = validate(config);
source-map:init时会慢,以后rebuild快
devtool: 'source-map',