Webpack学习总结
来源:互联网 发布:qq采集分析软件 编辑:程序博客网 时间:2024/06/10 03:39
Webpack学习总结
- Webpack学习总结
- Webpack 与 Gulp Grunt 对比
- 安装
- 1 创建packagejson文件
- 2 安装Webpack作为依赖包
- 3 创建目录文件夹
- 使用
- 1 编写基础代码
- 2 命令行基本使用
- 3 通过配置文件使用
- 4 更快捷地执行打包任务
- 功能扩展
- 1 生成Source Maps简化调试
- 2 构建本地服务器
- 3 Loaders
- 31 实例1配置读取 json 文件
- 32 实例2配置 babel
- 33 实例3配置 css-loader style-loader
- 34 实例4配置 CSS module
- 35 实例5配置 CSS预处理器
- 插件
- 1 区别 Loaders 和 Plugins
- 2 使用插件
- 21 实例1banner-plugin
- 22 实例2HtmlWebpackPlugin
- 23 实例3Hot Module Replacement
- 产品阶段的构建
- 1 创建 webpackproductionconfigjs 文件
- 2 配置 packagejson
- 3 优化插件
- 4 缓存
1. Webpack 与 Gulp / Grunt 对比
WebPack : 模块化解决方案(模块打包机),能够分析项目结构,找到JavaScript模块及浏览器不能直接运行的拓展语言(Scss,TypeScript等),转换和打包为合适的格式供浏览器使用。WebPack把项目当做一个整体,通过一个给定的主文件(如:index.js)开始找到项目的所有依赖文件,使用loaders处理,最后打包为一个(或多个)浏览器可识别的JavaScript文件
Gulp/Grunt : 前端开发流程优化工具,在配置文件中指明对某些文件进行编译、组合、压缩等任务的具体步骤并自动完成
2. 安装
2.1 创建package.json文件
# 创建标准的npm说明文件npm init# 回车默认即可
2.2 安装Webpack作为依赖包
# 全局安装npm install -g webpack# 安装到项目目录npm install --save-dev webpack
2.3 创建目录文件夹
创建两个文件夹:app 和 public,app文件夹存放原始数据和编写的JavaScript模块,public文件夹存放供浏览器读取的文件(包括使用webpack打包生成的js文件及一个index.html
文件)
webpack sample project|-- node_modules/|-- app/| |-- Greeter.js| |-- main.js|-- public/| |--index.html|-- package.json
3. 使用
3.1 编写基础代码
index.html 用于测试引入打包后的js文件(暂定名为bundle.js
)
<!-- index.html --><!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <title>Webpack Sample Project</title> </head> <body> <div id='root'> </div> <script src="bundle.js"></script> </body></html>
Greeter.js 中定义一个返回包含问候信息的html
元素的函数,并依据CommonJS规范导出这个函数为一个模块
// Greeter.jsmodule.exports = function() { var greet = document.createElement('div'); greet.textContent = "Hi there and greetings!"; return greet;};
main.js 把Greeter模块
返回的节点插入页面。
//main.js const greeter = require('./Greeter.js');document.querySelector("#root").appendChild(greeter());
3.2 命令行基本使用
webpack可以在终端中使用,在基本的使用方法如下:
# {extry file} 处填写入口文件的路径,本文中就是上述main.js的路径,# {destination for bundled file} 处填写打包文件的存放路径# 填写路径的时候不用添加{}webpack {entry file} {destination for bundled file}
未全局安装webpack时需要额外指定其在node_modules中的地址
# webpack非全局安装的情况,后同node_modules/.bin/webpack app/main.js public/bundle.js
3.3 通过配置文件使用
创建 websocket 配置文件 webpack.config.js
module.exports = { entry: __dirname + "/app/main.js",// 唯一入口文件 output: { path: __dirname + "/public",// 打包后的文件存放路径 filename: "bundle.js"// 打包后输出文件的文件名 }}
注:“__dirname” 是 node.js 中的全局变量,指向当前执行脚本所在的目录
打包文件只需命令行执行 webpack
,将自动引用 webpack.config.js
文件中的配置选项
webpack
3.4 更快捷地执行打包任务
对npm
进行配置后可以使用 npm
引导任务执行,在命令行中使用简单的 npm start
命令替代略微繁琐的命令 node_modules/.bin/webpack
,在 package.json
中对 scripts
对象进行相关设置:
{ "name": "webpack-sample-project", "version": "1.0.0", "description": "Sample webpack project", "scripts": { "start": "webpack" // 修改此处,JSON文件不支持注释,引用时清除 }, "author": "csxiaoyao", "license": "ISC", "devDependencies": { "webpack": "^1.12.9" }}
注:
package.json
中的script
会按一定顺序寻找命令对应位置(包含本地的node_modules/.bin
),所以全局或局部安装的Webpack都不需要指明详细的路径- npm的
start
命令特殊,npm start
可直接执行其对应的命令,而如果脚本名称不是start
,需执行npm run {script name}
如npm run build
npm start
4. 功能扩展
4.1 生成Source Maps(简化调试)
通过配置 devtool
,webpack
可以在打包时生成 source maps
,为开发者提供一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,更容易调试,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
选项具有相似的缺点上述选项由上到下打包速度越来越快,同时也具有越来越多的负面作用,对中小型的项目,eval-source-map
是一个很好的选项,但只应该开发阶段使用,对 webpack.config.js
进行如下配置:
module.exports = { devtool: 'eval-source-map', ...}
4.2 构建本地服务器
Webpack
提供了一个基于node.js构建的可选的本地开发服务器,可以让浏览器监听代码修改,并自动刷新显示,安装依赖并配置,更多配置参考 https://webpack.js.org/configuration/dev-server
npm install --save-dev webpack-dev-server
true
,当源文件改变时自动刷新页面 historyApiFallback 依赖 HTML5 history API,如果设置为true
,所有跳转将指向index.html(开发单页应用)修改配置文件 webpack.config.js
module.exports = { ... devServer: { contentBase: "./public",// 本地服务器根目录 historyApiFallback: true,// 不跳转 inline: true// 实时刷新 } }
在 package.json
中的 scripts
对象中添加命令以开启本地服务器
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "server": "webpack-dev-server --open"},
开启本地服务器,在8080
端口查看结果
npm run server
4.3 Loaders
通过使用不同的loader
,webpack
能调用外部的脚本或工具,实现对不同格式的文件处理,比如分析转换scss为css,或把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React可以把JSX文件转换为JS文件
Loaders需单独安装并在 webpack.config.js
中配置 modules
,Loaders配置包括:
test
:匹配loaders处理文件的拓展名的正则表达式(必须)loader
:loader名称(必须)include/exclude
:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)query
:为loaders提供额外的设置选项(可选)
4.3.1 实例1:配置读取 json 文件
把 Greeter.js
中的问候消息单独存放于 config.json
{ "greetText": "Hi there and greetings from JSON!"}
更新 Greeter.js
var config = require('./config.json');module.exports = function() { var greet = document.createElement('div'); greet.textContent = config.greetText; return greet;};
注:由于
webpack3.*/webpack2.*
已内置可处理JSON文件,所以无需再添加webpack1.*
需要的json-loader
4.3.2 实例2:配置 babel
Babel是一个编译JavaScript的平台(ES6、ES7、JSX…),Babel有一些模块化的包,核心功能位于babel-core
的npm包中,webpack可以把其不同的包整合在一起使用,对每个需要的功能或拓展需要安装单独的包(如解析Es6的babel-preset-es2015
包和解析JSX的babel-preset-react
包)
- 安装依赖模块
# npm一次性安装多个依赖模块,模块之间用空格隔开npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
- 配置
webpack
module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: [ "es2015", "react" ] } }, exclude: /node_modules/ } ] }};
- 安装
react
npm install --save react react-dom
- 使用ES6语法,更新
Greeter.js
并返回一个React组件
// Greeter.jsimport React, {Component} from 'react'import config from './config.json';class Greeter extends Component{ render() { return ( <div> {config.greetText} </div> ); }}export default Greeter
- 修改
main.js
,使用ES6的模块定义和渲染Greeter模块
import React from 'react';import {render} from 'react-dom';import Greeter from './Greeter';render(<Greeter />, document.getElementById('root'));
- 重新打包
npm start
访问
localhost:8080
查看效果使用单独的配置文件配置Babel
为简化Babel配置,把babel的配置选项单独放在 .babelrc
配置文件中(webpack会自动调用)
module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ } ] }};
新建 .babelrc
文件
{ "presets": ["react", "es2015"]}
4.3.3 实例3:配置 css-loader & style-loader
webpack提供两个工具处理样式表,css-loader
使开发者能够使用类似@import
和 url(...)
的方法实现 require()
的功能,style-loader
将所有的计算后的样式加入页面中,二者组合把样式表嵌入webpack打包后的JS文件中
- 安装依赖模块
npm install --save-dev style-loader css-loader
- 配置
webpack
module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" } ] } ] }};
注:注意此处对同一个文件引入多个loader的方法
- 在app文件夹中创建
main.css
文件
/* main.css */html { box-sizing: border-box; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;}*, *:before, *:after { box-sizing: inherit;}body { margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;}h1, h2, h3, h4, h5, h6, p, ul { margin: 0; padding: 0;}
- 入口文件导入
main.css
文件
//main.jsimport React from 'react';import {render} from 'react-dom';import Greeter from './Greeter';import './main.css';//使用require导入css文件render(<Greeter />, document.getElementById('root'));
4.3.4 实例4:配置 CSS module
CSS modules 技术意在把 JS 的模块化思想带入 CSS 中,通过CSS模块,所有的类名,动画名默认都只作用于当前模块,不必担心在不同的模块中使用相同的类名造成冲突
- 配置
webpack
module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true } } ] } ] }};
- 在app文件夹下创建
Greeter.css
文件
.root { background-color: #eee; padding: 10px; border: 3px solid #ccc;}
- 导入
.root
到Greeter.js
中,相同的类名也不会造成不同组件之间的污染
import React, {Component} from 'react';import config from './config.json';import styles from './Greeter.css';//导入class Greeter extends Component{ render() { return ( <div className={styles.root}>//添加类名 {config.greetText} </div> ); }}export default Greeter
- CSS modules 更多详见官方文档https://github.com/css-modules/css-modules
4.3.5 实例5:配置 CSS预处理器
Sass
和 Less
等预处理器是对原生CSS的拓展,允许使用 variables
, nesting
, mixins
, inheritance
等不存在于CSS中的特性来写CSS,CSS预处理器可将其转化为浏览器可识别的CSS语句,常用的CSS 处理loaders
:
Less Loader
Sass Loader
Stylus Loader
此外存在一个更强大的CSS的处理平台-PostCSS
https://github.com/postcss/postcss ,例如使用PostCSS为CSS代码自动添加适应不同浏览器的CSS前缀
- 安装
postcss-loader
和autoprefixer
(自动添加前缀插件)
npm install --save-dev postcss-loader autoprefixer
- 配置
webpack
//webpack.config.jsmodule.exports = { ... module: { rules: [ { 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" } ] } ] }}
- 在根目录新建
postcss.config.js
文件
// postcss.config.jsmodule.exports = { plugins: [ require('autoprefixer') ]}
- 重新使用
npm start
打包,css会自动根据Can i use里的数据添加不同前缀
5. 插件
5.1 区别 Loaders 和 Plugins
loaders 在打包构建过程中处理源文件(JSX,Scss,Less..),一次处理一个
Plugins 直接作用于整个构建过程,不直接操作单个文件
5.2 使用插件
5.2.1 实例1:banner-plugin
添加版权声明插件,插件地址:https://webpack.js.org/plugins/banner-plugin ,修改配置文件,打包后的JS文件中会插入版权信息
const webpack = require('webpack');module.exports = { ... plugins: [ new webpack.BannerPlugin('版权所有,翻版必究') ],};
5.2.2 实例2:HtmlWebpackPlugin
HtmlWebpackPlugin 插件依据一个简单的index.html
模板,生成一个自动引用打包后的JS文件的新index.html
(添加hash
值给js文件生成版本)
- 安装依赖
npm install --save-dev html-webpack-plugin
- 修改项目结构
移除public文件夹,index.html
文件会自动生成,在app目录下创建 index.tmpl.html
文件模板(包含title
等必须元素),编译过程中插件会自动添加所依赖的 css、js、favicon 等文件,并生成最终的html页面
<!-- index.tmpl.html --><!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8"> <title>Webpack Sample Project</title> </head> <body> <div id='root'> </div> </body></html>
- 更新
webpack
配置文件,新建build
文件夹存放最终的输出文件
const webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, ... plugins: [ new webpack.BannerPlugin('版权所有,翻版必究'), new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html"// 创建插件实例,并传入相关参数 }) ],};
- 执行
npm start
,build文件夹下生成bundle.js
和index.html
5.2.3 实例3:Hot Module Replacement
Hot Module Replacement
(HMR)允许在修改组件代码后自动刷新实时预览
- 安装
react-transform-hmr
npm install --save-dev babel-plugin-react-transform react-transform-hmr
- 配置Babel
// .babelrc{ "presets": ["react", "es2015"], "env": { "development": { "plugins": [["react-transform", { "transforms": [{ "transform": "react-transform-hmr", "imports": ["react"], "locals": ["module"] }] }]] } }}
- 配置
webpack
const webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, devtool: 'eval-source-map', devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true, hot: true }, module: { rules: [ { 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" } ] } ] }, plugins: [ new webpack.BannerPlugin('版权所有,翻版必究'), new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html"// 创建插件实例,并传入相关参数 }), new webpack.HotModuleReplacementPlugin()// 热加载插件 ],};
- 使用React时可以热加载模块,每次保存能在浏览器上看到更新内容
6. 产品阶段的构建
在产品阶段,还需要对打包的文件进行额外的处理,如优化、压缩、缓存及分离CSS和JS
6.1 创建 webpack.production.config.js 文件
// webpack.production.config.jsconst webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, devtool: 'eval-source-map', devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true, hot: true }, module: { rules: [ { 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" } ] } ] }, plugins: [ new webpack.BannerPlugin('版权所有,翻版必究'), new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html"// 创建插件实例,并传入相关参数 }), new webpack.HotModuleReplacementPlugin()// 热加载插件 ],};
6.2 配置 package.json
//package.json{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "server": "webpack-dev-server --open", "build": "NODE_ENV=production webpack --config ./webpack.production.config.js --progress" }, "author": "csxiaoyao", "license": "ISC", "devDependencies": { ... }, "dependencies": { "react": "^15.6.1", "react-dom": "^15.6.1" }}
6.3 优化插件
OccurenceOrderPlugin
:(内置)为组件分配ID,分析和优先考虑使用最多的模块并为它们分配最小的IDUglifyJsPlugin
:(内置)压缩JS代码ExtractTextPlugin
:分离CSS和JS文件- 安装依赖
npm install --save-dev extract-text-webpack-plugin
- 配置
webpack
// webpack.production.config.jsconst webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');const ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = { entry: __dirname + "/app/main.js", output: { path: __dirname + "/build", filename: "bundle.js" }, devtool: 'none', devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true, hot: true }, module: { rules: [ { 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" } ] } ] }, plugins: [ new webpack.BannerPlugin('版权所有,翻版必究'), new HtmlWebpackPlugin({ template: __dirname + "/app/index.tmpl.html" }), new webpack.optimize.OccurrenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin(), new ExtractTextPlugin("style.css") ],};
- 执行
npm run build
6.4 缓存
webpack可以把哈希值添加到打包的文件名中,添加特殊的字符串混合体([name], [id] and [hash])到输出文件名前
module.exports = { ... output: { path: __dirname + "/build", filename: "bundle-[hash].js" }, ...};
- Webpack学习总结
- webpack学习常用命令总结
- webpack 学习总结
- 如何配置webpack(学习总结)
- webpack总结
- Webpack 总结
- webpack学习
- Webpack学习
- webpack学习
- webpack学习
- webpack学习
- webpack学习
- webpack学习
- 学习webpack
- webpack学习
- webpack学习
- webpack学习
- webpack学习
- POJ1182 食物链(并查集)
- 接口的多继承和实现
- MDO3054示波器的使用
- Eclipse中用git解决冲突----避免每次重新拉代码
- css3选择器、背景、边框、渐变、阴影以及文本效果的介绍及实现
- Webpack学习总结
- solr优缺点
- POJ 2229 Sumsets
- 2008迎接元宵邀请赛
- ActiveMQ 5.x 的安全配置
- debug和masm对指令的不同处理和内存的另一种表示方法
- emacs+cedet使用
- 百度鹰眼轨迹窗口,显示自定义温度字段
- 栈