Webpack 学习总结
1.Webpack的特性
webpack 模块打包机,分析你的项目结构,找到JavaScript模块以及其他一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),将其打包为合适的格式以供浏览器使用。
webpack具有requireJs和browserify的功能,但仍有很多自己的新特性:
1. 对 CommonJS 、 AMD 、ES6的语法做了兼容
2. 对js、css、图片等资源文件都支持打包
3. 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScript、ES6的支持
4. 有独立的配置文件webpack.config.js
5. 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间
6. 支持 SourceUrls 和 SourceMaps,易于调试
7. 具有强大的Plugin接口,大多是内部插件,使用起来比较灵活
8.webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
Webpack和Grunt, Gulp的区别:
Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,然后这个工具自动替你完成这些任务。(Do a series of tasks)
Webpack的工作方式是,把项目当做一个整体,通过给定一个主文件entry(index.js),Webpack 将从这个文件开始找到项目的所有依赖文件,使用loaders处理他们,最后打包为浏览器可识别的JavaScript文件。(从入口文件查找下载依赖) 效率更高,打包更好。
2.开始使用Webpack
webpack 可以作为全局的npm模块安装,也可以在当前项目中安装。
npm install -g webpack
npm install --save-dev webpack
在终端的最基础命令:webpack {entry file/入口文件} {destination for bundled file/存放bundle.js的地方} 只需要一个入口文件,webpack将自动识别项目所依赖的其他文件。
如果是非全局安装,直接在命令行下执行 node_modules/.bin/webpack,就会自动读取webpack.config.js文件中的配置,输出打包后的文件。
在项目的package.son 文件中配置,实现快速打包:
{
"name": "webpack-sample-project",
"version": "1.0.0",
"description": "Sample webpack project",
"scripts": {
"start": "webpack" //配置的地方就是这里啦,相当于把npm的start命令指向webpack命令
},
"author": “dd”,
"license": "ISC",
"devDependencies": {
"webpack": "^1.13.2",
}
}
在项目中通过配置webpack.config.js 文件来使用Webpack, Webpack的强大功能都体现在配置文件中。下面是一个基本配置示例:
var path = require('path'); module.exports = {
entry: path.resolve(__dirname, './src/index.js'), //已多次提及的唯一入口文件 output: {
path: path.resolve(__dirname, './bundle'), //打包后的文件存放的地方 filename: 'bundle.js' //打包后输出文件的文件名 }, module: {
loaders: [
{ test: /\.js?$/, loaders: ['babel'], exclude: /node_modules/ },
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/}
]
}, resolve:{
extensions:['','.js','.json']
},
}; 注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
(1)entry
entry参数定义了打包后的入口文件,可以是个字符串或数组或者是对象;如果是数组,数组中的所有文件会打包生成一个filename文件;如果是对象,可以将不同的文件构建成不同的文件。
{ entry: { page1: "./page1", //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出 page2: ["./entry1", "./entry2"] }, output: { path: "dist/js/page", publicPath: "/output/", filename: "[name].bundle.js" } }
该段代码最终会生成一个 page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/page 文件夹下
(2)output
output参数是个对象,定义了输出文件的位置及名字:
output: { path: "dist/js/page", publicPath: "/output/", filename: "[name].bundle.js" }
path: 打包文件存放的绝对路径
publicPath: 网站运行时的访问路径
filename:打包后的文件名
当我们在entry中定义构建多个文件时,filename可以对应的更改为[name].js用于定义不同文件构建后的名字。
(3)module
module: { //加载器配置 loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.css$/, loader: 'style-loader!css-loader' }, //.js 文件使用 jsx-loader 来编译处理 { test: /\.js$/, loader: 'jsx-loader?harmony' }, //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理 { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, //图片文件使用 url-loader 来处理,小于8kb的直接转为base64 { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }
在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等静态文件都是模块,不同模块的加载是通过模块加载器(webpack-loader)来统一管理的。loaders之间是可以串联的,一个加载器的输出可以作为下一个加载器的输入,最终返回到JavaScript上。
(4)resolve
webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀:
resolve: { //查找module的话从这里开始查找 root: '/pomy/github/flux-example/src', //绝对路径 //自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名 extensions: ['', '.js', '.json', '.scss'], //模块别名定义,方便后续直接引用别名,无须多写长长的地址 alias: { AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 即可 ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' } }
然后我们想要加载一个js文件时,只要require('common')就可以加载common.js文件了。
注意一下, extensions 第一个是空字符串 '' 对应不需要后缀的情况.
(5)externals
当我们想在项目中require一些其他的类库或者API,而又不想让这些类库的源码被构建到运行时文件中,这在实际开发中很有必要。此时我们就可以通过配置externals参数来解决这个问题:
externals: {
"jquery": "jQuery"
}
(6)devtool使调试变得更容易
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选项具有相似的缺点;
(7)devServer 构建本地服务器
contentBase: 默认webpack-dev-server会为根文件夹提供本地服务器, 如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录
port: 设置默认监听端口,如果省略,默认为”8080“
inline: 设置为true,当源文件改变时会自动刷新页面
colors: 设置为true,使终端输出的文件为彩色的
historyApiFallback: 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
(8)loader配置
通过使用不同的loader,webpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理,
比如说分析JSON文件并把它转换为JavaScript文件,或者说把下一代的JS文件(ES6,ES7)转换为现代浏览器可以识别的JS文件。
或者说对React的开发而言,合适的Loaders可以把React的JSX文件转换为JS文件。
Loaders需要单独安装并且需要在webpack.config.js下的modules关键字下进行配置,
Loaders的配置选项包括以下几方面:
test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)
loader:loader的名称(必须)
include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
query:为loaders提供额外的设置选项(可选)
安装babel,babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。如果不复杂,可以直接在webpack.config.js中进行配置。
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader', options: { cacheDirectory: true, presets: ['env', 'stage-2', 'react'], plugins: ['transform-runtime'], }, }
css Loader处理:
test: /\.(less|css)$/, use: [ { loader: 'style-loader', }, { loader: 'css-loader', options: { minimize: false, sourceMap: true, }, }, { loader: 'postcss-loader', options: { plugins: postcss, //自动添加适应不同浏览器的前缀 }, }, { loader: 'less-loader', options: { sourceMap: true, }, }, ]
npm一次性安装多个依赖模块,模块之间用空格隔开,安装babel 常用的依赖
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
(9)plugins
const plugins = [ // plugin for passing in data to the js, like what NODE_ENV we are in. new webpack.DefinePlugin(config.globals), new webpack.optimize.CommonsChunkPlugin({ names: ['common', 'vendor', 'manifest'], minChunks: 2, }), new webpack.NoEmitOnErrorsPlugin(), //Hot Module Replacement(HMR)也是webpack里很有用的一个插件,它允许你在修改组件代码后,自动刷新实时预览修改后的效果。在webpack中实现HMR也很简单,只需要做两项配置。
/**在webpack配置文件中添加HMR插件,在Webpack Dev Server中添加“hot”参数;
devServer: { hot: true }
*/ new webpack.HotModuleReplacementPlugin(), /**在入口文件中index.js中: if (module.hot) { module.hot.accept(‘./home.js’); //接收这个文件的修改用来热加载 module.hot.accept('./routes', () => { //路由的改变将造成热加载,重新渲染 render(createRouter) }) }
*/ new webpack.NamedModulesPlugin(), //HtmlWebpackPlugin 这个插件的作用是依据一个简单的模板(index.template.html),
//帮你生成最终的Html5文件,这个文件中自动引用了你打包后的JS文件。每次编译都在文件名中插入一个不同的哈希值。
new HtmlWebpackPlugin({ title: 'ACTIVE Reader Cloud Dev', inject: true, chunksSortMode: 'dependency', filename: 'index.html', template: paths.base('build/index.template.html'), }) ]
在package.json文件中:
devDependencies 里面的插件只用于开发环境,不用于生产环境,而 dependencies 是需要发布到生产环境的,安装的时候注意控制。
3.Webpack3的新特性
6月20日发布了webpack3, 它和2有什么区别?
(1)更新方法以及版本迁移
通过命令直接安装即可,后面需要加上版本号。
npm install webpack@3.0.0 --save-dev
(2)scope hoisting
webpack2处理后的每个模块均被一个函数包裹,如下:
/* 50 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { window.lib = {} ... /* harmony default export */ __webpack_exports__["a"] = (window.lib); /***/ }),
这样会带来一个问题:降低浏览器中JS执行效率,这主要是闭包函数降低了JS引擎解析速度。
于是webpack团队参考Closure Compiler和Rollup JS,将一些有联系的模块,放到一个闭包函数里面去,通过减少闭包函数数量从而加快JS的执行速度。
webpack3通过设置ModuleConcatenationPlugin使用这个新特性:
module.exports = { plugins: [ new webpack.optimize.ModuleConcatenationPlugin() ] };
(3)Magic Comments
用于动态引入ES Module,webpack将传入import方法的模块打包到一个单独的代码块(chunk),但是却不能像require.ensure一样,为生成的chunk指定chunkName,因此在webpack3中提出了Magic Comment用于解决该问题,用法如下:
import(/* webpackChunkName: "my-chunk-name" */ 'module');
其实就是可以命令 chunk name 了.
Webpack接下来的还会持续有的新特性:
- 更好的编译缓存
- 更快的首次以及增量编译速度
- 对 TypeScript 更加友好地支持
- 修改 Long term caching
- 增加对 WASM Module 的支持
- 用户体验的改进
小伙伴们敬请期待吧...
Webpack 学习总结的更多相关文章
- 【原】webpack学习笔记
之前在react的项目中有用过webpack,不过没有认真的去研究,这段时间又重新好好的学习一下webpack,发觉 webpack是一个很强大的东西.而且很好用,方便,接下来主要是做一下学习的笔记 ...
- webpack学习(入门基础)
webpack的学习webpack是什么?1:加载模块(将JS.sass/less.图片等作为模块来处理使用) 2:进行打包 webpack的优势?1:webpack以commonJS(JS的规范)的 ...
- webpack学习笔记(二)-- 初学者常见问题及解决方法
这篇文章是webpack学习第二篇,主要罗列了本人在实际操作中遇到的一些问题及其解决方法,仅供参考,欢迎提出不同意见. 注:本文假设读者已有webpack方面相关知识,故文中涉及到的专有名词不做另外解 ...
- webpack学习笔记一:安装webpack、webpack-dev-server、内存加载js和html文件、loader处理非js文件
一 .webpack学习环境准备: 1:window系统 2:安装node.js 官方网址 下载好后下一步下一步安装即可 安装步骤略过....... 3:nrm的安装 打开cmd命令控制台 输入:n ...
- Webpack学习-Plugin
原文地址:http://wushaobin.top/2019/03/15/webpackPlugin/ 什么是Plugin? 在Webpack学习-工作原理(上)一文中我们就已经介绍了Plugin的基 ...
- webpack 学习资料
webpack 学习资料 webpack 学习资料 网址 webpack 中文版 https://webpack.docschina.org/configuration/dev-server/
- webpack学习(六)—webpack+react+es6(第3篇)
接上篇 : webpack学习(六)—webpack+react+es6(第2篇) 上篇其实是有问题的,问题在取服务器数据这块.this.props 表示那些一旦定义,就不再改变的特性,而 this. ...
- webpack学习(六)—webpack+react+es6(第2篇)
接上篇 webpack学习(五)—webpack+react+es6(第1篇) 本文做个简单的图片加文字的页面.其中,配置文件跟上篇一致.项目结构: index.html <!DO ...
- webpack学习(五)—webpack+react+es6(第1篇)
如果你看过webpack学习系列的前一个文章,接下来做的东西会比较简单 :webpack学习(四)— webpack-dev-server react发展的很快,现在大部分开发react相关的项目,都 ...
- webpack学习(三)
前篇:webpack学习(二) jquery不需要在项目中自己下载,而是作为一个模块引入.jquery的存放路径是在 node_modules目录下.1.首先给项目安装jquery,npm insta ...
随机推荐
- 大数据 - hadoop三台linux虚拟服务器 - 初始化部署
搭建hadoop环境 1.解压Hadoop的安装包,解压到modules文件夹中.(安装包下载地址:http://archive.apache.org/dist/hadoop/core/hadoop- ...
- Oracle12c的安装
直接下一步不多说高级安装可以选择设置,嫌麻烦可以直接典型安装(少些设置步骤)这里随便命用户名,口令即密码此处可以改安装路径可以根据电脑自身配置更改,但建议高于20%(给的越少,Oracle运行速度越慢 ...
- 商品规格,自定义SKU类型
<html> <head> <script type="text/javascript" src="http://xoxco.com/exa ...
- office2013 Word 缺少校对工具,按提示下载、安装了文件还是不成功的解决方案
找到你的office安装源iso镜像加载 ——点开镜像双击setup.exe ——选择添加或删除功能 ——下一步——其他的不要动,展开office共享功能项 ——找到校对工具点出下拉项(点朝下的黑色箭 ...
- POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)
pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态.求一种合法状态,使得终状态全为关闭: sol:模2意义下的高斯消元. 终于自己手打了一个初级板子. #include& ...
- Java基于opencv—透视变换矫正图像
很多时候我们拍摄的照片都会产生一点畸变的,就像下面的这张图 虽然不是很明显,但还是有一点畸变的,而我们要做的就是把它变成下面的这张图 效果看起来并不是很好,主要是四个顶点找的不准确,会有一些偏差,而且 ...
- java————数组 简单写出一个管理系统
数组的特点 1, 数组是一块连续的空间,下标描述空间的位置. 2, 下标从0开始,最大下标为数组长度—1.(*.length-1) 3, 数组元素都是变量.(就是每个下标对应的内容).变量的类型 ...
- VBA随机地牢生成
无聊啊--于是,我想做一个随机地图. 但是我很懒,不想做. 但是身体很诚实. 这次是直接在Excel中制作的地图,但是,VB的执行效率很慢,我代码的效率也很慢,导致,一旦地图长宽稍大,就会出现好几分钟 ...
- Mysql--基础(一)
MySQL基础 一.数据库的操作 1.SQL分类: DDL(数据定义语言) :数据定义语言 - Data Definition Language,用来定义数据库的对象,如数据表.视图.索引等.常用 ...
- Taro 代码及功能,需要注意的地方
Taro 代码不能使用的写法: 请注意无 AppID 关联下,调用 wx.operateWXData 是受限的, API 的返回是工具的模拟返回