一、webpack的基础配置
- 本地安装webpack
- 初始化 yarn init -y
yarn add webpack webpack-cli -D
- npx webpack 执行webpack
- webpack可以进行0配置
- 打包工具->输出的结果(js模块)
- 打包(支持js模块化),module.exports+require
- 手动配置webpack
- 默认配置文件的名字 webpack.config.js
- webpack.config.js
// webpack是node写出来的
let path = require('path');
module.exports = {
mode: 'development', // 模式 默认两种 production development
entry: './src/index.js', // 入口
output: {
filename: 'bundle.js', // 打包后的文件
path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
}
}
3. 配置文件可以是webpack.config.js也可以是webpackfile.js
二、webpack打包出的文件解析
- 解析配置后的文件
- 自定义配置文件
$ npx webpack --config webpack.config.my.js
- 脚本配置 package.json
"scripts": {
"build": "webpack --config webpack.config.my.js"
},
三、Html插件
- 开发服务器的配置插件 webpack-dev-server
- 安装:
$ cnpm i webpack-dev-server ;执行:$ webpack-dev-server;
- package.json
"scripts": {
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server"
},
- 开发服务器的配置webpack.config.js
devServer: { // 开发服务器的配置
port: 3000,
progress: true,
contentBase: './build',
compress: true
},
- 模板插入脚本 html-webpack-plugin
- 安装:
$ cnpm i html-webpack-plugin
- webpack.config.js
let HtmlWebpackPlugin = require('html-webpack-plugin');
output: {
filename: 'bundle.[hash:8].js', // 1. 打包后的文件 2. 每次修改产生新的文件,防止覆盖
path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
minify:{ // 压缩html
removeAttributeQuotes: true, // 删除html双引号
collapseWhitespace:true // html变成一行
},
hash: true // 设置hash戳
})
]
四、样式处理1
- loader
- 模块转换
- 特点:功能单一
- 用法:字符串只用一个loader,多个loader需要[],还可以写成对象方式
- loader的顺序,默认是从右向左执行,从下向上
- 安装插件
$ cnpm i less less-loader css-loader style-loader
- less less-loader css-loader style-loader node-sass sass-loader stylus stylus-loader
- css-loader 接续 @import这种语法
- style-loader 把css插入到head的标签中
- webpack.config.js
module: { // 模块
rules: [ // 规则
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
options: {
insertAt: 'top'
}
},
'css-loader'
]
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
options: {
insertAt: 'top'
}
},
'css-loader',
'less-loader'
]
}
]
}
五、样式处理2
- 抽离css文件
- 安装插件 mini-css-extract-plugin
- webpack.config.js 添加
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({
filename: 'main.css'
})
],
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
]
},
- 自动给css填前缀 -webkit-...
- 安装插件 postcss-loader autoprefixer
- 根目录新建postcss.config.js
module.exports = {
plugins: [require('autoprefixer')]
}
- webpack.config.js 添加
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
- 压缩css:插件mini-css-extract-pluin,搜索npmjs.org查找
- webpack.config.js 添加
let OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
let UglifyJsPlugin = require('uglifyjs-webpack-plugin');
optimization: { // 优化项
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin()
]
},
六、转化es6语法
- babel转化es6 => es5
- 安装插件:babel-loader @babel/core @babel/preset-env
- webpack.config.js 添加
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [ // 预设
'@babel/preset-env'
]
}
}
]
},
- 解析es7语法
class A {a=1};
- 安装插件 @babel/plugin-proposal-class-properties
- webpack.config.js 添加
options: {
presets: [ // 预设
'@babel/preset-env'
],
plugins:[
"@babel/plugin-proposal-class-properties"
]
}
- 解析装饰器语法
@log class A{a=1} function log(target){console.log(target)}
- 安装插件 @babel/plugin-proposal-decorators
- webpack.config.js 添加
options: {
presets: [ // 预设
'@babel/preset-env'
],
plugins:[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
七、处理js语法及校验
- 公共方法抽离
- 安装插件
$ cnpm i @babel/runtime @babel/plugin-transform-runtime -S;
- 使用 webpack.config.js 修改
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [ // 预设
'@babel/preset-env'
],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }],
"@babel/plugin-transform-runtime"
]
}
},
include: path.resolve(__dirname, 'src'), // 只解析include包括文件
exclude: /node_modules/ // exclude 排除掉node_modules;
},
- 高级语法(例:'aaa'.includes('a');)解析:
- 安装插件
@babel/polyfill
- 在使用文件中引入
require('@babel/polyfill');
- eslint代码校验:
- eslint网站下载.eslintrc.json
- 安装插件
$ cnpm i eslint eslint-loader eslint-friendly-formatter -D
- webpack.config.js 添加
{
test: /\.js$/,
loader: 'eslint-loader',
enforce: 'pre',
include: path.resolve(__dirname, 'src'),
options: {
formatter: require('eslint-friendly-formatter')
},
exclude: /node_modules/
},
八、全局变量引入问题
- 引入jquery
$ cnpm i jquery -S
- 使用jquery
import $ from 'jquery';或var $ = require('jquery');
- 使用expose-loader 暴露 全局的jquery 内联的loader
- pre 前面执行的loader normal 普通loader 内联loader 后置postloader
- 安装插件 expose-loader 使用
import $ from 'expose-loader?$!jquery';, 引入模块配置:webpack.config.js
{
test: require.resolve('jquery'),
use: 'expose-loader?$'
},
- 使用插件对每个模块注入jquery,webpack.config.js
let webpack = require('webpack');
plugins: [
new webpack.ProvidePlugin({ // 在每个模块中注入jquery
$: 'jquery'
})
],
- 使用cdn,引用但不打包juqery,webpack.config.js
externals: { jquery: 'jQuery' },
- 总结
- expose-loader 暴露到window上
- providePlugin给每个模块提供一个$
- 使用cdn,引入但不打包
九、图片处理
- 在js中创建图片来引入
let image = new Image();
image.src = '.logo.png'; // 这样就是一个普通的字符串,不会被打包
document.body.appendChild(image);
import logo from './logo.png'; // 把图片引入,返回的结果是一个新的图片地址
let image = new Image();
image.src = logo;
document.body.appendChild(image);
- 安装 file-loader
- webpack.config.js 添加
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'file-loader'
},
- 在css引入 background('url')
- 直接引入图片地址,使用file-loader
require('./index.css');
- 在HTML页面中直接插入图片:
<img src="" alt="" />
{
test: /\.html$/,
loader: 'html-withimg-loader'
},
- url-loader 做一个限制 图片大小<是多少k,用base64转化;图片大小>n*K,图片正常产出
{
test: /\.(png|jpg|jpeg|gif)$/,
use:{
loader: 'url-loader',
options:{
limit: 20*1024 // 20*1024 base64;1 正常产出
}
}
},
十、打包文件分类
- css放在一个css文件夹下,图片放到images文件夹下
new MiniCssExtractPlugin({
filename: 'css/main.css'
}),
{
test: /\.(png|jpg|jpeg|gif)$/,
use:{
loader: 'url-loader',
options:{
limit: 1,
outputPath: 'img/',
}
}
},
- publicPath 在引入文件前添加域名前缀
output: {
filename: 'bundle.[hash:8].js', // 1. 打包后的文件 2. 每次修改产生新的文件,放置覆盖
path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
publicPath: 'http://localhost...'
},
- 只给图片添加前缀 publicPath,给某一个资源添加cdn
{
test: /\.(png|jpg|jpeg|gif)$/,
use:{
loader: 'url-loader',
options:{
limit: 1,
publicPath: 'http://localhost/img'
}
}
},
package.json
{
"name": "webpack4",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server"
},
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"autoprefixer": "^9.6.0",
"babel-loader": "^8.0.6",
"css-loader": "^3.0.0",
"expose-loader": "^0.7.5",
"file-loader": "^4.0.0",
"html-webpack-plugin": "^3.2.0",
"html-withimg-loader": "^0.1.16",
"jquery": "^3.4.1",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.7.0",
"postcss-loader": "^3.0.0",
"style-loader": "^0.23.1",
"url-loader": "^2.0.1",
"webpack": "^4.35.2",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/polyfill": "^7.4.4",
"@babel/runtime": "^7.4.5"
}
}
webpack.config.js
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development', // 模式 默认两种 production development
entry: './src/index.js', // 入口
output: {
filename: 'bundle.[hash:8].js', // 1. 打包后的文件 2. 每次修改产生新的文件,放置覆盖
path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
// publicPath: 'http://localhost'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
minify: { // 压缩html
removeAttributeQuotes: true, // 删除html双引号
collapseWhitespace: true // html变成一行
},
hash: true // 设置hash戳
}),
new MiniCssExtractPlugin({
filename: 'css/main.css'
}),
],
module: { // 模块
rules: [ // 规则
{
test: /\.html$/,
loader: 'html-withimg-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 1,
outputPath: 'img/',
// publicPath: 'http://localhost/img'
}
}
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [ // 预设
'@babel/preset-env'
],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }],
"@babel/plugin-transform-runtime"
]
}
},
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader'
]
}
]
}
}