源码参见https://github.com/Ching-Lee/webpack-dev
webpack安装
具体步骤参见官网
官网:https://www.webpackjs.com/guides/getting-started/
webpack安装
前提需要安装node.js,webpack建议安装到项目目录下而非全局
- 首先建立一个空目录webpack_learn
- 进入该目录,并初始化
cd webpack-learn
npm init -y
会发现多出一个package.json文件在目录下 - 安装webpack,对于4.0以上版本需要安装webpack-cli
npm install webpack webpack-cli --save-dev
文件目录结构中增加node_modules,package.json,package-lock.json
webpack可以进行0配置
- 打包工具->输出后的结果(js模块)
-
打包:支持js模块化
webpack手动基础配置
- 默认配置文件的名字是webpack.config.js
在目录下创建一个webpack.config.js文件
const path = require('path');
module.exports = {
entry: './src/index.js', //入口文件
output: {
filename: 'bundle.js',// 出口文件
path: path.resolve(__dirname, 'dist')
},
//mode默认有两种 开发模式:development(方便开发时看) 生产模式:production(默认)
mode:'development'
};
文件会生成到dist目录下的bunlle.js中
-
可以在执行时添加--config参数+配置文件名,来指定文件
npx webpack --config webpack.config.js
但这样很长不方便,所以我们可以在package.js中将该命令写入scripts脚本。
运行npm run build
引入html打包插件html-webpack-plugin
目的:将src中的html文件经webpack打包后,自动生成到dist目录下,并且将src中的js文件加入到生成的dist目录下的html中。
-
插件安装
- 在webpack.config.js中配置插件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js', //入口文件
output: {
filename: 'bundle.js',// 出口文件
path: path.resolve(__dirname, 'dist')
},
// 数组 放着所欲的Webpack插件
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html',// 源文件
filename:'index.html' // 生成文件
})
],
//mode默认有两种 开发模式:development(方便开发时看) 生产模式:production(默认)
mode:'development'
};
打包之后看到dist目录下出现index.html文件,并且其中引入了脚本
我们希望生成的dist目录下的html被压缩
// 数组 放着所欲的Webpack插件
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html',// 源文件
filename:'index.html', // 生成文件
minify:{
removeAttributeQuotes:true, //取消标点
collapseWhitespace:true, //取消空格
},
hash:true
})
],
启用webpack-dev-server
目前我们只能通过静态页面来访问html,我们希望通过ip和端口号来访问。
webpack内置了此种服务,其内部是用express实现的
-
安装webpack-dev-server
-
启动服务
同时我们可以对开发服务器进行配置
在webpack.config.json中添加
module.exports = {
devServer:{ //开发服务器的配置
port:3000, //端口号
},
在package.json添加执行脚本
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js",
"dev":"webpack-dev-server"
},
启动
样式处理
- 安装插件
- webpack.config.js中添加配置
// 通过此模块,能够将在insex.js中import的所有.css结尾的文件,
// 打包到html中的head标签里面
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
-
src中新建css样式,并在js中引入
-
再次启动
npm run dev
可以看到在head中把样式加了进去
样式处理2
之前生成的css是直接使用内联的方式插入到html中的。
现在我们将css直接抽离成一个文件。
这里使用的插件是 mini-css-extract-plugin
- 安装
- 更改配置
const MiniCssExtractPlugin=require('mini-css-extract-plugin');
// 数组 放着所需要的Webpack插件
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html',// 源文件
filename:'index.html', // 生成文件
minify:{
removeAttributeQuotes:true, //取消标点
collapseWhitespace:true, //取消空格
},
hash:true
}),
new MiniCssExtractPlugin({
filename:'style.css'
})
],
// 通过此模块,能够将在insex.js中import的所有.css结尾的文件,
// 打包到html中的head标签里面
module: {
rules: [
{
test: /\.css$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
-
npm run build之后可以看到css文件
为css中样式自动加前缀webkit等
插件:postcss-loader autoprefixer
- 修改配置
module: {
rules: [
{
test: /\.css$/,
use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
// 添加
'postcss-loader',
]
}
]
},
同时需要新建一个postcss.config.js文件
src中的css
生成的css
压缩css,js
-
压缩css
插件 optimize-css-assets-webpack-plugin
- 压缩js
插件uglifyjs-webpack-plugin
- 修改配置文件
module.exports = {
// 添加这个部分
optimization:{
minimizer:[
new UglifyJsPlugin({
cache:ture,
parallel:true,
sourceMap:true
}),
new OptimizeCss()
]
},
转化ES6语法
我们需要将ES6转化成ES5语法
所有插件可以在babel官网自助查询https://babeljs.io/
插件:babel-loader @babel/core @babel/preset-env
- 修改配置,添加语法
module: {
rules: [
// 用于转换es6语法
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env'
]
}
}
},
- 对于class类的语法,还是不会支持,需要插件
@babel/plugin-proposal-class-properties
- 对于装饰器@,需要插件
npm install --save-dev @babel/plugin-proposal-decorators
修改配置
module: {
rules: [
// 用于转换es6语法
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env'
],
// 支持ES7装饰器,class语法
plugins:[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
}
},
- 对于generator,include语法,需要插件@babel/runtime
npm install --save @babel/runtime
npm install --save-dev @babel/plugin-transform-runtime
plugins:[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }],
"@babel/plugin-transform-runtime"
]
校验js代码是否符合规范ESLint
npm install --save-dev eslint eslint-loader
module: {
rules: [ //loader默认是从右向左,从下到上执行。
// 用户处理js语法校验
{
test:/\.js$/,
use:{
loader:'eslint-loader',
options:{
enforce:'pre' //previous post
}
}
},
在官网进行配置https://eslint.org/demo/,并下载eslintrc.json放到项目中,重命名为.eslintrc.json
webpack打包图片
- 在js中创建图片引用
npm install --save-dev file-loader
配置图片相应规则
// 图片相关规则
{
test:/\.(png|jpg|gif)$/,
use:'file-loader'
}
js中创建图片并引用
// 打包图片
// 1.在js中创建图片并引用
// file-loader默认会在内部生成一张图片到build目录下,并且把生成的图片名字返回回来
let image=new Image();
console.log(logo);
image.src=logo;
document.body.appendChild(image);
- 在css中使用图片
直接使用即可
body{
background: url('./logo.png') repeat;
}
js中引入样式
import './index.css'
- 在html里面直接引入图片
插件:html-withimg-loader
npm install --save-dev html-withimg-loader
配置
// 在html中能使用图片
{
test:/\.html$/,
use:'html-withimg-loader'
}
- 优化file-loader
一般使用url-loader
npm install --save-dev url-loader
对图片配置进行修改
// 图片相关规则
{
test:/\.(png|jpg|gif)$/,
//use:'file-loader'
// 做一个限制,当图片小于多少时,使用base64来转化,
// 否则使用file-loader产生真实图片
use:{
loader:'url-loader',
options:{
limit:200*1024
}
}
},
打包资源分类
我们希望图片去一个目录,css去一个目录
在options中添加outputPath属性。
// 图片相关规则
{
test:/\.(png|jpg|gif)$/,
//use:'file-loader'
// 做一个限制,当图片小于多少时,使用base64来转化,
// 否则使用file-loader产生真实图片
use:{
loader:'url-loader',
options:{
//limit:200*1024,
limit:1,
outputPath:'/img/',
// 也可以根据情况单独添加
//publicPath:'http://ww.123.cn'
}
}
},
// 将css抽象到dist/css
new MiniCssExtractPlugin({
// 改文件路径
filename:'css/style.css'
})
],
结果
同时我们可以设置所有资源的根目录,publicPath,用于CDN加速,这里我们只对图片进行了加速,可以看到结果。