什么是webpack
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
可以做的事情
代码转换、文件优化、代码分割、模块合并、自动刷新、代码校验、自动发布
复制代码
需要提前掌握的内容
- 需要node基础,以及npm的使用
- 掌握es6语法
主要学习webpack哪些内容
- webpack常见配置
- webpack高级配置
- webpack优化策略
- ast抽象语法树
- webpack中的Tapable
- 掌握webpack流程,手写webpack
- 手写webpack中常见的loader
- 手写webpack中常见的plugin
创建文件
mkdir webpack-test && cd webpack-test
mkdir src
touch src/index.js
复制代码
初始化文件
npm init -y 初始文件(默认的)
npm init
复制代码
开始打包
npx webpack
复制代码
配置webpack.config.js
touch webpack.config.jsconst path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {devServer: { // 开发服务器的配置contentBase: path.join(__dirname, 'dist'),compress: true,port: 3000},mode: 'development', // 模式 默认两种production developmententry: './src/index.js', //入口output: {filename: 'bundle.js', //打包后的文件名path: path.resolve(__dirname, 'dist'), //路径必须是一个绝对路径},plugins: [// 数组放着所有的webpack插件new HtmlWebpackPlugin({template: './src/index.html',filename: 'index.html'})]
}
复制代码
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><div id="root"></div><script src="bundle.js"></script>
</body>
</html>
复制代码
index.js
var root = document.getElementById("root");
root.innerHTML="你好"
复制代码
webpack常见配置
npm i webpack webpack-cli -D
npm i html-webpack-plugin -D
复制代码
使用模板 html
- html-webpack-plugin 可以指定template模板文件,将会在output目录下,生成html文件,并引入打包后的js.
npm i html-webpack-plugin -D
复制代码
webpack-dev-server
- webpack-dev-server提供了一个简单的Web服务器和实时热更新的能力
npm i webpack-dev-server -D
复制代码
pagkage.js
{"name": "webpack-test","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "webpack-dev-server","build": "webpack"},"keywords": [],"author": "","license": "ISC","devDependencies": {"html-webpack-plugin": "^3.2.0","webpack": "^4.30.0","webpack-cli": "^3.3.0","webpack-dev-server": "^3.3.1"}
}复制代码
目前的目录
启动项目
npm run dev
复制代码
浏览器输入http://localhost:3000/
加载样式文件
- 在src目录下创建一个index.css
body{background-color:red;
}
复制代码
- 在index.js中引入index.css
require('./index.css');
复制代码
- webpack.config.js增加一些参数
module: { //模块rules: [ // 规则 css-loader // style-loader 把css插入到head的标签中// loader的特点: 希望单一// loader的用法: 字符串只用一个loader// 多个loader需要[]// loader的顺序 默认是从右向左执行// loader还可以写出对象方式{test: /\.css$/,use: ['style-loader','css-loader']},]
}
复制代码
- css-loader style-loader
npm i css-loader style-loader -D
复制代码
- 效果如下
加载less(sass,stylus类似)
- 在src目录下创建一个index.less
body{#root{border:1px yellow solid;color: #000;}
}
复制代码
- 在index.js中引入index.less
require('./index.css');
复制代码
- webpack.config.js增加一些参数
{test: /\.less$/,use: [{loader: 'style-loader',},'css-loader','less-loader']},
复制代码
- less-loader
npm i less less-loader -D
复制代码
- 效果如下
提取单独打包css文件
npm i mini-css-extract-plugin -D
复制代码
- webpack.config.js增加一些参数
const MiniCssExtractPlugin = require('mini-css-extract-plugin');plugins: [ new MiniCssExtractPlugin({filename: 'main.css'})],
module: { //模块use: [MiniCssExtractPlugin.loader,]},{test: /\.less$/,use: [MiniCssExtractPlugin.loader,]}]}
复制代码
css3样式自动加前缀
npm i postcss-loader autoprefixer -D
复制代码
- 在webpack-test创建postcss.config.js
module.exports = {plugins: [require('autoprefixer')]
}
复制代码
- webpack.config.js增加一些参数
{test: /\.css$/,use: [{loader: 'style-loader',// options: {// insertAt: 'top' //内联样式最高级// }},'css-loader','postcss-loader']},{test: /\.less$/,use: [{loader: 'style-loader',},'css-loader','postcss-loader','less-loader']
}
复制代码
转化es6语法
npm i babel-loader @babel/core @babel/preset-env -D
npm i @babel/plugin-proposal-class-properties -D
复制代码
- webpack.config.js增加一些参数
rules: [
{
test: /\.js$/,
use: {loader: 'babel-loader',options: { // 用babel-loader 需要把es6-es5presets: ['@babel/preset-env'],plugins: ['@babel/plugin-proposal-class-properties']}
}
]
复制代码
全局变量引入
npm i jquery -D
npm i expose-loader -D
复制代码
第一种
- import $ from 'jquery';
- webpack.config.js增加一些参数
rules: [ {test: require.resolve('jquery'),use: 'expose-loader?$'},
]
复制代码
第二种
- webpack.config.js增加一些参数
const webpack = require('webpack');
plugins: [ // 数组放着所有的webpack插件new webpack.ProvidePlugin({$: 'jquery' // 在每个模块中注入$对象})
],
复制代码
引入图片处理
// 1.在js中创建图片来引入
// 2.在css引入backgroud('url')
// 3.<img src="" alt="" />>
npm i file-loader -D
npm i html-withimg-loader -D
复制代码
- webpack.config.js增加一些参数
rules: [ {test: /\.html$/,use: 'html-withimg-loader'},{test: /\.(png|jpg|gif)$/,use: 'file-loader'},
]
复制代码
- 限制图片大小
npm i url-loader -D
复制代码
- webpack.config.js增加一些参数
{test: /\.(png|jpg|gif)$/,use: {loader: 'url-loader',options: {limit: 200*1024}}
复制代码
images和css打包分类
- webpack.config.js增加一些参数
plugins: [ // 数组放着所有的webpack插件new MiniCssExtractPlugin({filename: 'css/main.css'}),
],
{test: /\.(png|jpg|gif)$/,use: {loader: 'url-loader',options: {limit: 1,outputPath: '/img/',publicPath: 'https://www.baidu.com' // 在图片上加域名}}
复制代码
多页面打包
- 在scr创建一个other.js
console.log("other 一路走好!")
复制代码
- webpack.config.js增加一些参数
// 多入口
entry: {index: './src/index.js', home: './src/other.js',
},
output: {filename: '[name].js', //打包后的文件名path: path.resolve(__dirname, 'dist'), //路径必须是一个绝对路径// publicPath: 'https://www.baidu.com'
},
plugins: [ // 数组放着所有的webpack插件new HtmlWebpackPlugin({template: './src/index.html',filename: 'index.html',chunks: ['index']}),new HtmlWebpackPlugin({template: './src/index.html',filename: 'home.html',chunks: ['home']}),
]
复制代码
配置source-map调试代码
- webpack.config.js增加一些参数
output: {filename: '[name].js', //打包后的文件名path: path.resolve(__dirname, 'dist'), //路径必须是一个绝对路径// publicPath: 'https://www.baidu.com'
},
// devtool: 'source-map', // 1.增加映射文件 可以帮我们调试源代码
// devtool: 'eval-source-map', // 2.不会产生单独的文件,但是可以显示行和列
// devtool: 'cheap-module-source-map', // 3.不会产生列,但是是一个单独的映射文件(产生后你可以保留起来)
devtool: 'cheap-module-eval-source-map',// 4.不会长生文件,集成在打包后的文件中不会产生列
复制代码
watch实时打包
- webpack.config.js增加一些参数
entry: {index: './src/index.js', home: './src/other.js',
},
watch: true,
watchOptions: { // 监控的选项poll: 1000, // 每秒问我1000次aggregateTimeout: 500, // 防抖ignored: /node_modules/ // 不需要进行监控哪个文件
},
复制代码
常用的小插件
- 清除dist (clean-webpack-plugin)
- 拷贝文件(copy-webpack-plugin)
- 版权注释(bannerPlugin)
npm i clean-webpack-plugin -D
npm i copy-webpack-plugin -D
复制代码
- 在webpack-test创建doc文件,里面创建hello.txt
- webpack.config.js增加一些参数
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
plugins: [ new CleanWebpackPlugin(),new CopyWebpackPlugin([{from: 'doc', to: './'}]),new webpack.BannerPlugin('cl by 2019')
],
复制代码
webpack跨域问题
npm i express -D
复制代码
- 1)webpack代理
- 在webpack-test目录下创建server.js
let express = require('express');
let app = express();
app.get('/user', (req, res)=> {res.json({ name: "xiaolin3333" })
})
app.listen(3000);
复制代码
- webpack.config.js配置
devServer: { // 开发服务器的配置// 1)http:proxyproxy: {// 重新的方式 把请求代理到express服务器!'/api': {target: 'http://localhost:3000',pathRewrite: {'/api': ''}} // 配置了一个代理}},
复制代码
- index.js
let xhr = new XMLHttpRequest();xhr.open('GET', '/api/user', true);xhr.onload = function() {console.log(xhr.response,);
}xhr.send();
复制代码
- 启动 node server.js && npm run dev
- 2)前端只想单纯来模拟数据
- webpack.config.js配置
devServer: { // 开发服务器的配置// 2)前端只想单纯来模拟数据before(app) { // 提供的方法 钩子app.get('/user', (req, res)=> {res.json({ name: "xiaolinwww" })})}
复制代码
- index.js
let xhr = new XMLHttpRequest();
xhr.open('GET', '/user', true);xhr.onload = function() {console.log(xhr.response,);
}xhr.send();
复制代码
- 启动 npm run dev
- 3)有服务端 不想用代理来处理 能不能再服务端中启动webpack端口用服务端口
npm i webpack-dev-middleware -D
复制代码
- server.js
let express = require('express');let app = express();
let webpack = require('webpack');// 中间件
let middle = require('webpack-dev-middleware');let config = require('./webpack.config');let compiler = webpack(config);app.use(middle(compiler));app.get('/user', (req, res)=> {res.json({ name: "xiaolin3333-webpack-dev-middleware" })
})app.listen(3000);
复制代码
- index.js
let xhr = new XMLHttpRequest();
xhr.open('GET', '/user', true);xhr.onload = function() {console.log(xhr.response,);
}xhr.send();
复制代码
- 启动 node server && http://localhost:3000/
resolve属性的配置
yarn add css-loader style-loader -D
复制代码
- index.js
import './style';style.cssbody{background-color:green;transform: rotate(90deg);
}
复制代码
- webpack.config.js配置
resolve: {// 解析第三方包 commonmodules: [path.resolve('node_modules')],extensions: ['.js','.css','.vue']
// alias: { // 别名 vue vue.runtime
// bootstrap: 'bootstrap/dist/css/bootstrap.css'
// },
// mainFields: ['style', 'main']
// mainFields: [],// 入口文件的名字index.js
},module: { //模块rules: [ {test: /\.css$/,use: ['style-loader','css-loader']},]
}
复制代码
项目文件未更新
- github.com/chenlin1/we…