本文是针对TCM项目所作的WebPack配置文件总结,主要概述了一些经常使用配置选项和插件使用,对之后的项目有指导意义。
TCM的webpack配置文件包括webapck.config.base.js、webapck.config.dev.js、webapck.config.prod.js三个基本文件, webpack.config.base.js是基本配置文件,webpack.config.dev.js是开发配置,webpack.config.prod.js是产品配置文件,webpack.config.base.js包含一些webpack.config.prod.js和webpack.config.base.js共有的基本配置,而webpack.config.prod.js和webpack.config.base.js在webpack.config.base.js的基础上添加了一些必要配置。为了引入Node的express API,经过dev.js和prod.js对顶层配置进行定义,所以,package.json文件的scripts部分定义了采用不一样配置进行开发的npm指令:css
如下较多内容是对《入门Webpack,看这篇就够了》作的总结,加入不少网上收集的资料,目的是为了更深的了解TCM中的WebPack配置。html
Node.js的发展使各类依赖普遍涌现,这些依赖包含各类插件、加载器,能够简化开发流程。模块化是前端发展的一大趋势,基于React的单页应用完美诠释了模块化的概念,经过组件的方式进行开发,组件之间互相引用,而且引用外部依赖。为了打包外部依赖以及本地JavaScript模块、SCSS模块、图片等,打包工具应运而生,以WebPack最为著名,相似的还有Gulp/Grunt等。webpack的优势之一就是把全部文件,包括CSS、HTML、图片、JavaScript代码等都视为模块处理,只要配置中包含相应的loader就能够进行处理打包。前端
其实Webpack和另外两个并无太多的可比性,Gulp/Grunt是一种可以优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优势使得Webpack能够替代Gulp/Grunt类的工具。
Grunt和Gulp的工做方式是:在一个配置文件中,指明对某些文件进行相似编译,组合,压缩等任务的具体步骤,这个工具以后能够自动替你完成这些任务。node
Webpack的工做方式是:把你的项目当作一个总体,经过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的全部依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。react
webpack有一个默认的配置文件webpack.config.js(官方文档),位于项目根目录,也能够根据须要建立多个配置文件,TCMngr配置了三个文件:webpack.base.conf.js/webpack.dev.config.js/webpack.prod.conf.js。在package.json的scripts中添加不一样的命令设置不一样的配置文件,在TCMngr的package.json中有jquery
"scripts": { "start": "cross-env NODE_ENV=development node build/dev.js", "build": "cross-env NODE_ENV=production node build/prod.js" },
能够看到此处使用了cross-env依赖包,这个包容许以UNIX的方式设置环境变量,并在windows上正常运行。安装命令:webpack
npm install cross-env --save-dev
webpack配置文件本质就是一个JavaScript module,可使用JavaScript语言,文件会导出一个配置对象,格式以下:git
mudule.exports = {};
全部的配置信息都在这个对象中体现,包括:
entry:打包的入口文件,可使一个字符串或一个对象,若是只有一个须要打包的模块,使用这种形式;若是是一个对象,对象对应的全部文件都被打包,该对象能够是包含多个打包模块的数组,依赖较强的排在前面,也能够是键值对,分别对应不一样的输出包,包名就是键名;TCM的webpack.base.conf.js指出了须要打包的文件,包含框架、类库以及入口源码。github
resolve:影响模块解析的设置,是一个对象,包含如下属性。web
resolve.extensions:自动识别的文件扩展名,若是你想请求一个js文件可是在请求时不带扩展 (如:require('index')),那么就须要将'.js'添加到数组中。并非必须配置这一选项,不配 置时会使用默认值["", ".webpack.js", ".web.js", ".js"],手动设置会致使默认值被覆 盖。若是想要每一个模块都能按照本身的扩展名解析,要加上空字符串。 resolve.modulesDirectories:目录名组成的数组,会在该目录以及该目录的顶层目录寻找依赖 模块,默认值是Default: ["web_modules", "node_modules"]。 resolve.root:包含依赖模块的绝对路径,多是目录数组
resolveLoader:设置和resolve设置相似,只不过是针对loaders设置。
output:打包的输出结果,是一个对象,包含如下属性:
filename:输出文件名,filename里面的[name]会由entry中的键替换; path:输出路径; publicpath:经过浏览器访问时的公共URL地址。
module:定义对模块的处理逻辑,是一个对象;
loaders:定义一系列自动加载的loader,是一个对象数组;
[ { test:正则表达式,用于匹配处理的文件 loader/loaders:字符串或数组,表示用到的加载器,loader:string表示用!分隔的loader,loaders:[]表示用到的加载器数组。 include:包含的文件夹 exclude:排除的文件夹 } ]
plugins:定义插件,一个数组,定义全部用到的插件。
externals:当咱们想在项目中require一些其余的类库或者API,而又不想让这些类库的源码被打包时,这在实际开发中颇有必要。此时咱们就能够经过配置externals参数来解决这个问题:
这样咱们就能够放心的在项目中使用这些API了:var jQuery = require(“jquery”);
devtool:选择调试工具,经常使用eval-source-map
//实例 { devtool: "#inline-source-map" }
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程当中生效,执行相关的任务。Loaders和Plugins经常被弄混,可是他们实际上是彻底不一样的东西,能够这么来讲,loaders是在打包构建过程当中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操做单个文件,它直接对整个构建过程其做用。要使用某个插件,咱们须要经过npm安装它,而后要作的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)。
通常安装在devDependency中:
npm install webpack-dev-server --save-dev
安装后使用webpack-dev-server便可在浏览器窗口观察输出,浏览器会自动打开项目根目录的index.html文件,默认端口号是8080,完整地址是http://localhost:8080/。使用命令webpack-dev-server --hot --inline完成自动刷新,为了简写命令,在package.json的scripts中添加以下语句:
“build” : “webpack-dev-server --hot --inline --config ‘webpack-dev-config.js’”
--config设置默认的webpack配置文件。
devserver做为webpack配置选项中的一项,具备如下配置选项
在webpack.config.js中体现为:
devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 colors: true,//终端中输出结果为彩色 historyApiFallback: true,//不跳转 inline: true//实时刷新 }
WebPack生成source maps,能够对应编译文件和源文件,使得编译后的代码可读性更高,更容易调试。配置source maps,须要配置devtool,它有如下四种不一样的配置选项,各具优缺点,描述以下:
上述选项由上到下打包速度愈来愈快,不过同时也具备愈来愈多的负面做用,较快的构建速度的后果就是对打包后的文件的的执行有必定影响。
在学习阶段以及在小到中性的项目上,eval-source-map是一个很好的选项,不过记得只在开发阶段使用它,以下配置
module.exports = { devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项 entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" } }
Babel工具包括babel-core/babel-loader/babel-preset-es2015/babel-preset-react,若是使用命令行还要安装babel-cli。
Babel的配置较为复杂,反映在webpack.config.js与.babelrc中,webpack.config.js会自动调用.babelrc中的配置选项。webpack.config.json会包含如下配置
//webpack.config.js { test: /\.js$/, exclude: /node_modules/, loader: 'babel' } //.babelrc { "presets": ["react", "es2015"] }
webpack提供两个工具处理样式表,css-loader 和 style-loader,两者处理的任务不一样,css-loader使你可以使用相似@import 和 url(...)的方法实现 require()的功能,style-loader将全部的计算后的样式加入页面中,两者组合在一块儿使你可以把样式表嵌入webpack打包后的JS文件中。
Sass 和 Less之类的预处理器是对原生CSS的拓展,它们容许你使用相似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器能够这些特殊类型的语句转化为浏览器可识别的CSS语句,在webpack里使用相关loaders进行配置就可使用了,经常使用的CSS 处理loaders包括Less Loader、Sass Loader、Stylus Loader。
// TCM中开发环境下直接内嵌 CSS 以支持热替换 // autoprefixer自动添加前缀的插件 config.module.loaders.push({ test: /\.css$/, loader: 'style!css!autoprefixer' }, { test: /\.less$/, loader: 'style!css!less!autoprefixer' }, { test: /\.scss$/, loader: 'style!css!sass!autoprefixer' });
var BrowserSyncPlugin = require('browser-sync-webpack-plugin'); config.plugins.push( new BrowserSyncPlugin({ host: '127.0.0.1', port: 9090,// 浏览器监听地址 proxy: 'http://127.0.0.1:9000/', logConnections: false, notify: false }, { reload: false }) );
使用该插件须要在webpack配置中增长如下声明:
var NyanProgressPlugin = require('nyan-progress-webpack-plugin'); plugins: [ new NyanProgressPlugin() ]
效果以下:
这个插件的做用是依据一个简单的模板,帮你生成最终的Html5文件,这个文件中自动引用了你打包后的JS文件。每次编译都在文件名中插入一个不一样的哈希值。
//安装 npm install --save-dev html-webpack-plugin //webpack.config.js var HtmlWebpackPlugin = require('html-webpack-plugin'); config.plugins.push( new HtmlWebpackPlugin({ filename: 'index.html', template: config.commonPath.indexHTML, //载入文件 chunksSortMode: 'auto' }) );
该插件的设置参数不少:
title: 设置title的名字
filename: 设置这个html的文件名
template:要使用的模块的路径
inject: 把模板注入到哪一个标签后 'body',
favicon: 给html添加一个favicon './images/favico.ico',
minify:是否压缩 {...} | false
hash:是否hash化 true false ,
cache:是否缓存,
showErrors:是否显示错误,
chunks:目前没太明白
xhtml:是否自动毕业标签 默认false
Hot Module Replacement(HMR)也是webpack里颇有用的一个插件,它容许你在修改组件代码后,自动刷新实时预览修改后的效果。在webpack中实现HMR也很简单,只须要作两项配置:在webpack配置文件中添加HMR插件;在Webpack Dev Server中添加“hot”参数。不过配置完这些后,JS模块其实仍是不能自动热加载的,还须要在你的JS模块中执行一个Webpack提供的API才能实现热加载,虽然这个API不难使用,可是若是是React模块,使用咱们已经熟悉的Babel能够更方便的实现功能热加载。Babel有一个叫作react-transform-hrm的插件,能够在不对React模块进行额外的配置的前提下让HMR正常工做。
//webpack中的配置 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); config.plugins.push( plugins: [ new webpack.HotModuleReplacementPlugin()//热加载插件 ] ); //安装react-transform-hmr npm install --save-dev babel-plugin-react-transform react-transform-hmr //Babel中的配置 { "presets": ["react", "es2015"], "env": { "development": { "plugins": [["react-transform", { "transforms": [{ "transform": "react-transform-hmr", "imports": ["react"], "locals": ["module"] }] }]] } } }
OccurenceOrderPlugin :为组件分配ID,经过这个插件webpack能够分析和优先考虑使用最多的模块,并为它们分配最小的IDUglifyJsPlugin:压缩JS代码;ExtractTextPlugin:分离CSS和JS文件