一:应用场景:
项目小,不必要用vue框架等单页框架
但是希望最后利用webpack打包项目,对项目体积优化,代码优。实现图片代码压缩
项目中需要用到 jq, rem适配,项目有缓存处理机制。
二:1.先看一下如下我的项目目录结构:
2.根目录创建的webpack.config.js 文件配置如下:
const path = require('path') // path模块是node.js的核心模块,主要用来操作文件路径
const webpack = require('webpack') // 引入已经安装的webpack模块
const HtmlWebpackPlugin = require('html-webpack-plugin') //引入 htmlwebpackplugin 插件 作用生成html文件
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') //引入extract-text-webpack-plugin 拆分css,将css从js中抽离,
const autoprefixer = require('autoprefixer');//给css自动加浏览器兼容性前缀的插件
const CleanWebpackPlugin = require('clean-webpack-plugin') // 每次打包前,先清空打包后生成的dist文件包
module.exports={
mode:'development', // 4.x 新增,提供 mode 配置选项,会将 process.env.NODE_ENV 的值设为 development, 启用相应环境模式下的 webpack 内置的优化
entry:{ //入口文件 1.只打包一个文件(单入口),写个字符串;2.把多个文件打包成一个文件,写个数组;3.把多个文件分别打包成多个文件,写成对象
//多入口文件
index:'./src/js/index.js',
list:'./src/js/list.js',
detail:'./src/js/detail.js',
common:'./src/js/common.js'
},
output:{
path:path.resolve(__dirname,'dist'), // __dirname:是node.js中的一个全局变量,它指向当前执行脚本所在的目录
filename:'js/[name]-[hash:5].js', //[chunkhash:5]: 数字和字母组成的8位哈希值,[name]:是根据入口文件的自动生成的,有几个入口文件,就可以打包几个出口文件。
publicPath: '/' //表示打包文件中引用文件的路径前缀,如果你的图片存放在CDN上,那么你上线时可以加上这个参数,值为CDN地址,这样就可以让项目上线后的资源引用路径指向CDN了。
// 表示线上地址: "http://glkj.com/"
// 例如: publicPath: 'http://cdn.example.com/assets/[hash]/'
},
module:{ // 配置模块 主要用于解析css图片转换压缩等功能
rules:[
{//解析js
test: '/\.(js|jsx)$/', // 正则匹配
use: [
{
loader:'babel-loader',
options:{// 该loader对应的参数
presets:['@babel/preset-env',],
plugins:['@babel/transform-runtime']
}
}
],
exclude: path.resolve(__dirname, 'node_modules'), //exclude 不包含node_modules中js文件
include: path.resolve(__dirname, 'src'), // include 包含src中的js文件
},
{//解析less
test: /\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader',
use:[// 从右向左解析
{loader:'css-loader'},
{loader:'less-loader'},
{
loader: 'postcss-loader', //
options: {
plugins: [
autoprefixer({
browsers: ['ie >= 8','Firefox >= 20', 'Safari >= 5', 'Android >= 4','Ios >= 6', 'last 4 version']
})
]
}
},
{
loader: 'px2rem-loader', // 解析less文件时,将px单位转换成rem单位。
options: {
remUnit: 75,//px转rem换算比率 1rem = 75px
remPrecision: 8 //保留小数点后到几位小数
}
}
]
})
},
{//解析 css
test:/\.css$/,
use:ExtractTextWebpackPlugin.extract({ // 将css从js中分离出来
fallback:'style-loader', // 回滚待查
use:[
{loader:'css-loader'},
{
loader: 'postcss-loader', //
options: {
plugins: [
autoprefixer({
browsers: ['ie >= 8','Firefox >= 20', 'Safari >= 5', 'Android >= 4','Ios >= 6', 'last 4 version']
})
]
}
},
{
loader: 'px2rem-loader', // 解析css文件时,将px单位转换成rem单位
options: {
remUnit: 75, //px转rem换算比率 1rem = 75px
remPrecision: 8 //保留小数点后到几位小数
}
}
]
})
},
{// 解析img图片
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader:'url-loader', // 将图片文件小于下方limit参数值的图片进行dataurl转码,转成base64路径啦(注意urlloader内置fileloader)
options:{
name: "[name]-[hash:5].min.[ext]", // 打包后的图片名
limit: 20000, // 单位是B, 1Kb =1000B size<=20kb 意思是 小于20kb的图片进行base64编码,而大于20kb则需要打包,这个打包也只是copy图片,并没有真正意义上压缩图片,压缩的话,需要安装压缩的loader
//publicPath:'../image', // 表示打包文件中引用文件的路径前缀,即此处表示图片的引用路径前缀,如果你的图片存放在CDN上,那么你上线时可以加上这个参数,值为CDN地址,这样就可以让项目上线后的资源引用路径指向CDN了。
outputPath: "image/" // 定义输出的图片路径
}
},
{
loader:'image-webpack-loader', // 图片压缩loader
options:{
bypassOnDebug: true // 待查
}
}
]
},
{
test: /\.html$/, // 打包html页面中的img图片
use: ["html-withimg-loader"] //打包html中的img标签中的图片,使用该loader图片会被打包,且路径处理得当,图片大的话也会直接压缩到dist目录中,小的话,直接转成base64路径引进去
},
]
},
plugins:[// 配置插件 用于生产模板等各项功能
new CleanWebpackPlugin(['dist']), // 打包前,先将dist文件中的内容全部清除
new webpack.ProvidePlugin({ // 自动加载模块插件 使用模块插件的时候,不需要通过 import/require引入 使用该模块
$:'jquery',
jQuery:'jquery'
}),
new HtmlWebpackPlugin({ //作用是打包生成对应的html文件
template:'./src/page/index.html', //要处理的html模板文件(打包后,生成新的html文件)
filename:'pages/index.html', // 打包生成的文件地址及文件名,filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
title:'index', // 设置该页面的title标题标签
chunks:['index','common'],
inject:'body', // 所有js资源插入到head标签中
}),
new HtmlWebpackPlugin({ //作用是打包生成对应的html文件
template:'./src/page/detail.html', //要处理的html模板文件(打包后,生成新的html文件)
filename:'pages/detail.html', // 打包生成的文件地址及文件名,filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
title:'detail', // 设置该页面的title标题标签
chunks:['detail','common'],
inject:'body', // 所有js资源插入到head标签中
}),
new HtmlWebpackPlugin({ //作用是打包生成对应的html文件
template:'./src/page/list.html', //要处理的html模板文件(打包后,生成新的html文件)
filename:'pages/list.html', // 打包生成的文件地址及文件名,filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
title:'list', // 设置该页面的title标题标签
chunks:['list','common'],
inject:'body', // 所有js资源插入到head标签中
}),
new ExtractTextWebpackPlugin('css/[name].css'), // 将从js中分离后的css文件放到指定目录(放到dist下css目录下)并引入到当前js坐在的页面
new webpack.HotModuleReplacementPlugin() // HotModuleReplacementPlugin为webpack内置插件调用使用webpack.[plugin-name]使用这些插件
],
devServer:{ // 配置本地开发服务器
contentBase:path.resolve(__dirname,'dist'),//webpack-dev-ser运行时的文件根目录 (将 dist 目录下的文件,作为搭建的开发服务器可访问的文件)
historyApiFallback:false,
host:'localhost', // 可以通过localhost访问
overlay:{
errors:true // 出现错误之后会在页面中出现遮罩层提示
},
inline:true,
stats: 'errors-only',
hot:true, // 启动热更新
open:true // 启用webpack-dev-server时,自动打开浏览器
},
devtool: 'inline-source-map' //是一个工具,主要是查看编译后的文件如果报错,控制台提示错误来自于编译前的哪一个文件。方便找错
}
说明文档:
// 插件使用的时候,npm下载然后引入到使用位置 。
// loader 下载下来就可以,无需引入。
// npm 安装同一个包的时候 --save 然后再安装同一个包–save-dev 在package.json中位置会从dependence移到devdependence
// 注意webpack4.0以后,除了安装webpack以后,还需要安装webpack-cli(此工具用于在命令行中运行 webpack) (如果你使用 webpack 4+ 版本,你还需要安装 CLI)
// html-webpack-plugin 作用是重新生成上线的html文件,new HtmlWebpackPlugin(参数)将对应的js,css引入到改html文件中
// extract-text-webpack-plugin 拆分css文件 打包的时候会将css文件从js文件中抽离出来,不是以内部样式表style的形式注入到当前页面,而是以link 形式外部引入,将CSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件
// 注意在安装 extract-text-webpack-plugin 时,使用npm install --save-dev extract-text-webpack-plugin@next,因为extract-text-webpack-plugin的默认版本是3.02,不支持webpack4.0及以上,而extract-text-webpack-plugin@next是4.0版本支持webpa4.0
// 或者使用 mini-css-extract-plugin也可以,代替extract-text-webpack-plugin
// 如果当前项目是webpack3.x版本,使用extract-text-webpack-plugin;
// 如果当前项目是webpack4.x版本(但已有extract-text-webpack-plugin配置),可以继续用extract-text-webpack-plugin,但必须用对应的beta版本,且这个beta版本不支持生成hash;
// 如果当前项目是webpack4.x版本且是新项目,使用mini-css-extract-plugin。
// ProvidePlugin 自动加载模块插件 不必通过 import/require 使用模块,使用的时候直接用参数中定义的变量即可使用加载的插件 例如: new webpack.ProvidePlugin({
//$: ‘jquery’,
//jQuery: ‘jquery’
//})
// style-loader 新建一个style标签,把css-loader处理过的文件放进去,然后插入到HTML标签中
// postcss-loader autoprefixer 结合使用 自动添加浏览器前缀 做浏览器兼容的,,less和css文件都要配置。
// 公共jq 第三方插件的打包 或单独打包
// 背景图和页面直接引入的图的打包使用 url-loader file-loader 注意urlloader中包含了fileloader,所以有urlloader就不用再安装file-loader了。
// url-loader 作用将图片大小小于在limit设置的参数内的图片路径转成base64码,
// file-loader 作用将图片大小大于在limit设置的参数外的图片copy一份放在对应参数配置的路径上去
// rem 插件使用(lib-flexible,px2rem-loader)
// 注释:一般情况下UI给出的设计图按照iPhone5或者iPhone6来设计的,设计图为真实设备的2x图
// flexible 1.原理真实设备下动态更改html字体的大小如设备宽750px html的font-size为75px 设备为375px html font-size为37.5px
// 然后页面的其他尺寸都按照rem为单位设置来实现自适应
// 安装使用方法:
// 1.安装lib-flexible,并qie引入到各个入口js文件中,
// 2.安装px2rem-loader ,然后分别对less文件和css文件进行配置。将样式中的px单位转换成rem单位,这样你就可以直接在样式中写px 打包后自动帮你转成rem
// webpack4的优点
// webpack3的时候要自己设置开发环境和生产环境,生产环境还要自己配置js压缩,各种压缩。
// webpack4告诉你完全没必要配置那些了,执行npm run build 即 package.json中的命令行 {“build”:“webpack --mode production” }即可,webpack4 就会自动打包进行压缩处理,所以不用比额外配置webpack插件去压缩了
//在本地模拟项目打包上线
// 1. 先在本地创建一个服务器 node环境下,npm install express -g
// 2. 最新版的express4.0版本中将命令工具分家出来,还需要安装一个命令工具:npm install -g express-generator
// 3. 创建一个express工程:express helloworld
// 4. 进入项目主目录:cd helloworld
// 5. 安装必备包:npm install
// 6. 到此,本地服务器创建完成。
// 7. 打开服务器目录,将打包生成的dist文件夹下的文件复制、粘贴至public目录下(注意是将dist内的文件复制粘贴而不是dist)
// 8. 运行 npm start , 然后打开浏览器,输入http://localhost:3000/index.html即看到项目线上效果了(注意: http://localhost:3000定位到public目录下,根据项目页面目录情况而定)
// package.json
//观察模式 配置
//在packge.json 编译命令后边加 “–watch” 即可 如: “dev”: “webpack --watch”
// 这样的话,只要你需要编译的文件一改动,watch 检查到就会自动编译,无需再次运行 npm run dev 命令
//命令行执行 webpack-dev-server 的作用
// 1.启动本地服务器,让dist打包后的代码在服务器上运行
// 2.执行 webpack-dev-server,其实它也打包了代码,只不过打包后的文件不会显示在项目的目录中,也不在硬盘中,而是打包到了运行内存中。这样便于开发环境开发,更加快捷。(在内存中进行代码的编译和资源的提供,但并不写入磁盘来提高性能)
{
"name": "webpack-duo-page-demo",
"version": "1.0.0",
"description": "webpack 多页打包demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server",
"dev": "webpack --watch",
"build": "webpack --mode production"
},
"author": "",
"license": "ISC",
"dependencies": {
"clean-webpack-plugin": "^1.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^3.0.1",
"html-withimg-loader": "^0.1.16",
"image-webpack-loader": "^4.6.0",
"jquery": "^3.3.1",
"path": "^0.12.7",
"url-loader": "^1.1.2",
"webpack": "^4.28.4"
},
"devDependencies": {
"autoprefixer": "^9.4.5",
"babel-core": "^6.26.3",
"babel-loader": "^8.0.5",
"babel-preset-env": "^1.7.0",
"cross-env": "^5.2.0",
"css-loader": "^2.1.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"lib-flexible": "^0.3.2",
"postcss-loader": "^3.0.0",
"px2rem-loader": "^0.1.9",
"style-loader": "^0.23.1",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
},
"babel": {
"presets": [
"env"
],
"plugins": []
},
"browserslist": [
"defaults",
"> 1%",
"last 2 versions",
"not ie <= 8",
"ios > 7"
]
}