一、简介
- 本质,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)
- 当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
- 四个核心:入口(entry)、输出(output)、loader、插件(plugins)
二、简单使用
注:需要node环境和node伴随的包管理工具npm,webpack也可以全局安装以方便使用
2.1 创建一个empty project,npm初始化,会自动创建package.json
npm init -y
安装webpack,经常使用的可以全局安装,尝试的就运行第二条
//全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack
注:全局安装有时候需要权限加sudo
2.2 简单构建项目结构
- 创建src文件夹,编写代码所需资源都放在此文件夹下,如js、css、images、less,或者html文件
- 创建out文件夹(起名public 或者其他全凭个人爱好),作为打包输出的,当然如果不想HTML文件打包,可以直接放在这个文件夹下面
注:上两条是一般项目结构,具体文件根据各自所需,以下Demo所需文件 - 在out文件夹下创建index.html并引入打包输出的bundle.js
Webpack Sample Project
- 在src下创建main.js作为入口文件以及main.css,Greeter.js作为测试js文件,Greeter.css作为测试css文件
// Greeter.js
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
return greet;
};
//main.js
const greeter = require('./Greeter.js');
document.querySelector("#root").appendChild(greeter());
/* Greeter.css */
.root {
background-color: #eee;
padding: 10px;
border: 3px solid #ccc;
}
- 修改下package.json方便打包,主要注释运行时清除
{
"name": "webpack-sample-project",
"version": "1.0.0",
"description": "Sample webpack project",
"scripts": {
"start": "webpack" // 修改的是这里,JSON文件不支持注释,引用时请清除
},
"author": "zhang",
"license": "ISC",
"devDependencies": {
"webpack": "3.10.0"
}
}
- 在工程目录下创建webpack.config.js webpack配置文件,建议在开发时使用eval-source-map,__dirname全局变量,文件所在的目录
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/src/main.js",
output: {
path: __dirname + "/out",
filename: "bundle.js"
}
}
- 打包检查,运行,不报错说明成功,会在out目录下看到bundle.js文件
npm start
2.3 使用webpack构建本地服务器
- 安装依赖,如果加-g为全局安装
npm install --save-dev webpack-dev-server
- 修改package.json以及webpack.config.js文件
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/src/main.js",
output: {
path: __dirname + "/out",
filename: "bundle.js"
},
devServer: {
contentBase: "./out",//本地服务器所加载的页面所在的目录
historyApiFallback: true,//不跳转
inline: true//实时刷新
}
}
package.json中添加
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack",
"server": "webpack-dev-server --open"
},
- 运行,成功会在浏览器中看到index.html页面,control+c会结束运行
npm server
devserver的配置选项 | 功能描述 |
---|---|
contentBase | 默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到“public"目录) |
port | 设置默认监听端口,如果省略,默认为”8080“ |
inline | 设置为true,当源文件改变时会自动刷新页面 |
historyApiFallback | 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html |
2.4 Loaders使用
- Loaders让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
2.4.1 json文件
- 无需添加依赖,webpack2及以上已经内置可处理JSON文件,这里我们无需再添加webpack1.*需要的json-loader
- 在src文件夹下添加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;
};
- 运行,看结果
npm start
2.4.2 Babel
- Babel其实是一个编译JavaScript的平台,让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持,以及使用基于JavaScript进行了拓展的语言,比如React的JSX;
- babel-core核心包
- babel-env-preset 解析Es6
- babel-preset-react 解析JSX
- 一般一次性安转多个包
- 安装依赖
// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react
- 在webpack中配置Babel
module.exports = {
entry: __dirname + "/src/main.js",//已多次提及的唯一入口文件
output: {
path: __dirname + "/out",//打包后的文件存放的地方
filename: "bundle.js"//打包后输出文件的文件名
},
devtool: 'eval-source-map',
devServer: {
contentBase: "./out",//本地服务器所加载的页面所在的目录
historyApiFallback: true,//不跳转
inline: true//实时刷新
},
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader",
options: {
presets: [
"env", "react"
]
}
},
exclude: /node_modules/
}
]
}
};
- 为了测试ES6以及JSX,安装React
npm install --save react react-dom
- 修改Greeter.js和main.js,使用React的ES6
//Greeter,js
import React, {Component} from 'react'
import config from './config.json';
export default class Greeter extends Component{
render() {
return (
{config.greetText}
);
}
}
// main.js
import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';
render( , document.getElementById('root'));
- 配置在下面,运行,看结果
- Babel可以在webpack中配置,也可以单独配置,单独的配置文件webpack会自动调用
//webpack 中添加
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader"
},
exclude: /node_modules/
}
]
}
单独配置需要在工程目录下创建.babelrc文件
//.babelrc
{
"presets": ["react", "env"]
}
2.4.3 CSS 文件
- css-loader使你能够使用类似@import 和 url(...)的方法实现 require()的功能
- style-loader将所有的计算后的样式加入页面中
- 安装依赖
npm install --save-dev style-loader css-loader
- 修改webpack 配置,在module对象的rules 数组中添加对象
{
loader: "style-loader"
}, {
loader: "css-loader",
options: {
modules: true, // 指定启用css modules
localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
}
}
- css 文件已在前面创建,在main.js中引入该css文件
//main.js
import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';
import './main.css';//使用require导入css文件
render( , document.getElementById('root'));
- 运行,看结果
- CSS module,通过CSS模块,所有的类名,动画名默认都只作用于当前模块
/* Greeter.css */
.root {
background-color: #eee;
padding: 10px;
border: 3px solid #ccc;
}
import React, {Component} from 'react';
import config from './config.json';
import styles from './Greeter.css';//导入
class Greeter extends Component{
render() {
return (
//使用cssModule添加类名的方法
{config.greetText}
);
}
}
export default Greeter
- CSS预处理器,Sass 和 Less 之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句
- 安装依赖
npm install --save-dev postcss-loader autoprefixer
2.webpack 配置
//webpack.config.js
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
}
}, {
loader: "postcss-loader"
}
]
}
]
}
}
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
2.5 插件(Plugins)使用
2.5.1 内置的版本声明的插件
- webpack配置
plugins: [
new webpack.BannerPlugin('版权所有,翻版必究')
]
-
运行,查看打包结果
2.5.2 HtmlWebpackPlugin
- 把html文件模板打包成html,自动引入js文件
- 安装
npm install --save-dev html-webpack-plugin
2.创建 index.tmpl.html
Webpack Sample Project
- 配置webpack,新建一个输出文件夹out2,如果继续使用out文件夹需要删除下面的文件
...
output: {
path: __dirname + "/out2",
filename: "bundle.js"
},
...
plugins: [
new webpack.BannerPlugin('版权所有,翻版必究'),
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
})
]
- 运行,查看结果,out2文件夹下会出现bundle.js和index.html文件
2.5.3 Hot Module Replacement
- 简称HMR,自动刷新实时预览修改效果
new webpack.HotModuleReplacementPlugin()//热加载插件
- HMR是webpack插件,使用时还需要对模块进行额外的配置
- react-transform-hrm Babel 插件,可以在不对React模块进行额外的配置的前提下让HMR正常工作
npm install --save-dev babel-plugin-react-transform react-transform-hmr
// .babelrc
{
"presets": ["react", "env"],
"env": {
"development": {
"plugins": [["react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}]
}]]
}
}
}
2.5.4 其他常用插件
- UglifyJsPlugin 压缩JS代码,内置插件
- ExtractTextPlugin 分离CSS和JS文件
npm install --save-dev extract-text-webpack-plugin
- OccurenceOrderPlugin 给组件分配ID,内置插件
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("style.css")
- clean-webpack-plugin 使用缓存时会把hash值添加到输出文件名,此插件解决缓存的多余文件
git
npm install --save-dev clean-webpack-plugin
const CleanWebpackPlugin = require("clean-webpack-plugin");
...
new CleanWebpackPlugin('build/*.*', {
root: __dirname,
verbose: true,
dry: false
})