把一堆的css文件和js文件放在一个总的入口文件,通过require引入,剩下的事情webpack会处理,包括所有模块的前后依赖关系,打包、压缩、合并成一个js文件。
一、步骤
1、新建文件夹:D:\Backup\桌面\webpack
D:\Backup\桌面\webpack\001 \项目1
2、在Visual Studio Code打开webpack文件夹,在此文件夹下新建001文件夹(项目名)
3、在终端,打开001文件夹,项目初始化:npm init
4、填写信息:
name:项目名称
version:项目版本号
description:对这个项目的描述,或者描述使用webpack的那些功能
entry point:入口文件名
test command:测试时候的命令
git repository:git上面的仓库名
keywords:关键词
author:作者名字
license:许可证
5、将webpack安装在项目里面,即和package.json统计目录:
终端里面输入:npm i webpack -g(全局安装)
npm i webpack-cli -g
npm i webpack -D
npm i webpack-cli -D
6、在001下面新建app文件夹(源代码模),在app文件夹下面新建文件index.js作为入口文件
index.js(引入css,json等文件):
console.log(‘hhhhh’);
// 引入data.json的数据
import data from ‘./data.json’
console.log(data);
//引入样式文件
import ‘./index.css’
在001下面新建build文件夹(打包输出模),
7、运行指令:生产环境比开发环境多一个压缩操作
开发环境:webpack ./app/index.js -o ./build/built.js --mode=development
生成环境:webpack ./app/index.js -o ./build/built.js --mode=production
输出结果:
8、新建一个js文件做配置文件,咱叫做webpack.config.js(与package.json同目录下)
webpack配置完(入口、输出、mode、loader等配置好)
9、下载相关的包(最好把所有包都下载到最外层,就不用每个项目都重复下载了)
npm i css-loader -D
npm i style-loader -D
npm i less-loader -D
npm i less -D
10、打包(运行指令:webpack)
11、新建html文件,引入打包好的js文件,右键运行就可以查看是否引用到。
打包html资源—plugins
1)下载包:npm install html-webpack-plugin -D
2)// 引入插件
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//插件---打包html资源
plugins: [
// new HtmlWebpackPlugin()默认创建一个html文件
// 复制./app/index.html的html文件,并自动引入打包输出的所有资源
new HtmlWebpackPlugin({template: './app/index.html'})
],
3)打包(运行指令:webpack)
打包图片资源-–样式中的图片路径
1)html文件引入css,css引入img
入口文件引入css样式文件:import ‘./index.css’
2)module配置----引入css中图片资源
// 图片小于8kb就会被base64处理,优点(减少请求数量),缺点(文件请求速度慢(体积大)
// esModule:关闭url-loader的es6模块化,使用commonjs解析
// [hash:10] 取图片hash的前10位
// [ext] 取文件原来扩展名,outputPath输出目录
{
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
options: { limit: 8 * 1024, esModule: false, name:'[hash:10].[ext]', outputPath: 'imgs'}
},
注意:这个loader默认处理不了html中的图片。
下载包:
npm install url-loader -D
npm install file-loader -D
3)plugins配置-----引入html
4)打包(运行指令:webpack)
引入html中的图片资源
html中:
1)module配置
{test: /\.html$/, loader: 'html-loader'},
下载包:npm install html-loader -D
2)打包(运行指令:webpack)
引入其他资源—icon和字体资源(阿里云https://www.iconfont.cn/)
1)下载阿里云的icon(下载代码)
挑选相应图标并获取类名,应用于html页面:(demo_index.html页面有说明使用方法和名字)
//
2)入口文件index.js中引入iconfont样式文件(复制字体和图标资源到项目中)
import ‘./iconfont/iconfont.css’
3)module配置
//打包其他资源(除html/js/css之外的资源:icon/font)
{ test: /\.(eot|svg|ttf|woff)$/, loader: 'url-loader'}
开发服务器devServer:(实时更新代码)
1)module配置
// 开发服务器:自动编译,自动打开浏览器,自动刷新浏览器
// 启动指令:npx webpack-dev-server
devServer:{
contentBase: resolve(__dirname, 'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 9090,
// 自动打开浏览器
open: true,
}
2)下载包(在本项目下安装):npm i webpack-dev-server -D
3)启动命令:npx webpack-dev-server(内存中编译打包,没有输出,实时更新)
webpack(打包结果输出)
使用场景
1、根据模板生成HTML,并自动处理上面的css/js引用路径
2、自动处理里面的图片路径,css里面背景图的路径,字体引用
3、开启本地服务器,一边改写代码,一边自动更新页面内容
4、编译jsx es6 sass less coffescript等,并添加md5、sourcemap等辅助
5、异步加载内容,不需要时不加载到DOM
6、配合vue.js react.js等框架开发
提取打包后的js文件中的css代码:
1)下载插件:npm i mini-css-extract-plugin -D
2)引入插件:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3)修改module的css配置:
{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader'] },
4)插件:
new MiniCssExtractPlugin({ filename: 'css/built.css'})
css兼容性处理:
1)下载包:npm i postcss-loader -D、npm i postcss-preset-env -D
2)module配置:
// 3、css兼容性处理
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
]
},
3)packsge.json配置
"browserslist": {
//开发环境:需要设置node.js环境变量:process.env.NODE_ENV = 'development'
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
//生产环境:默认选择(与mode的配置无关)
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
4)
//css兼容性:开发环境:需要设置node.js环境变量:
// process.env.NODE_ENV = ‘development’;
5)在built.css查看浏览器兼容性结果
压缩css:(压缩基本都是插件做的)
1)下载插件:npm i optimize-css-assets-webpack-plugin -D
2)引入:
// 压缩css的插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
3)插件配置
new OptimizeCssAssetsWebpackPlugin()
js语法检查:自动修复
1)下载包:npm i eslint -D、npm i eslint-loader -D、npm i eslint-config-airbnb-base -D、npm i eslint-plugin-import -D
2)module配置
// js语法检查--只检查自己写的,不检查第三方的
// 检查规则:pack.json中eslintConfig中设置。fix: true自动修复
{ test: /\.js$/, loader: 'eslint-loader', exclude: /node_modules/, options: { fix: true}},
3)packsge.json配置
"eslintConfig": {
"extends": "airbnb-base"
}
4)运行:webpack
js兼容性处理:
1)下载包:npm i babel-loader -D、npm i @babel/preset-env -D、npm i @babel/core -D
2)module配置:
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: ['@babel/preset-env']}},
二、简单的webpack.config.js代码:
// 基于node.js平台运行的---模块化默认采用common.js(此文件采用common.js语法)
const { resolve } = require('path');
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入从built.js文件分割css代码的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
// 入口起点
entry: './app/js/index.js',
// 输出
output: {
// 输出文件名
filename: 'js/built.js',
// 输出文件路径,__dirname是node.js的变量,代表当前文件的目录--绝对路径
path: resolve(__dirname, 'build'),
},
module: {
rules: [ // 配置loader
// { test: /\.js$/, loader: 'babel!jsx',exclude: /node_modules/ },
//{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
// MiniCssExtractPlugin插件将所有样式打包为单独的css文件,所以不需要style-loader,改为MiniCssExtractPlugin.loader
{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
// { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
// 引入样式中的图片资源
// 图片小于8kb就会被base64处理,优点(减少请求数量),缺点(文件请求速度慢(体积大)
// esModule:关闭url-loader的es6模块化,使用commonjs解析
// [hash:10] 取图片hash的前10位
// [ext] 取文件原来扩展名
{
test: /\.(png|jpg|gif)$/,
loader: 'url-loader',
options: { limit: 8 * 1024, esModule: false, name:'[hash:10].[ext]', outputPath: 'imgs'}
},
// 引入html中的图片资源
{test: /\.html$/, loader: 'html-loader'},
//打包其他资源(除html/js/css之外的资源)
{ test: /\.(eot|svg|ttf|woff)$/, loader: 'url-loader'}
// { exclude: /\.(html|js|css)/, loader: 'file-loader'}
],
},
//插件---打包html资源
plugins: [
// new HtmlWebpackPlugin()默认创建一个html文件
// 复制./app/index.html的html文件,并自动引入打包输出的所有资源
new HtmlWebpackPlugin({template: './app/index.html'}),
// 上面module的css配置需要改
new MiniCssExtractPlugin({ filename: 'css/built.css'})
],
// development 或 production
mode: 'development',
// 开发服务器:自动编译,自动打开浏览器,自动刷新浏览器
// 启动指令:npx webpack-dev-server
devServer:{
contentBase: resolve(__dirname, 'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 9090,
// 自动打开浏览器
open: true,
},
};
三、属性分析
1、入口(entry):
//entry表示入口,webpack执行构建的第一步将从entry开始,可以抽象成输入
entry: './app/entry',//只有一个入口,入口只有一个文件
entry: ['./app/entry1','./app/entry2'],//只有一个入口,入口有两个文件夹
entry: { //有两个入口
a: './app/entry-a',
b: ['./app/entry-b1','./app/entry-b2']
},
2、出口(output):
output: {
//输出文件存放的目录,必须是string类型的绝对路径
path: path.resolve(__diename,'dist'),
//输出文件的名称
filename: 'bundle.js',// 完整的名称
filename: '[name].js',//在配置了多个entry时,通过名称模板为不同的entry生成不同的文件名称
filename: '[chunkhash].js',//根据文件内容的hash值生成文件的名称,用于浏览器长时间缓存文件
//发布到线上的所有资源URL前缀,为string类型
publicPath: '/assets/', //放到指定目录下
publicPath: '', //放到根目录下
publicPath: 'https://cdn.example.com/', //放到CDN上
//导出库的名称,为string类型
//不填它时,默认的输出格式是匿名的立即执行函数
library: 'MyLibrary',
//导出库的类型,为枚举类型,默认是 var
//可以是umd、umd2、commonjs2、commonjs、amd、this、var、assign、window、global、jsonp
libraryTarget: 'umd',
//是否包含有用的文件路径信息生成的代码里,为boolean类型
pathinfoL:true,
//附加chunk的文件名称
chunkFilename: '[id].js',
chunkFilename: '[chunkhash].js',
//jsonp异步加载资源时的回调函数名称,需要和服务端搭配只用
jsonpFunction: 'myWebpackJsonp',
//生成的 Source Map 文件的名称
sourceMapFilename: '[file].map',
//浏览器开发行和工具里显示的源码模块名称
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]',
//异步加载跨域的资源时使用的方式
crossOriginLoading: 'use-credentials',
crossOriginLoading: 'anonymous',
crossOriginLoading: false,
},
3、loader:
module: {
rules: [ // 配置loader
{
test: /\.jsx?$/, //正则匹配命中要使用loader的文件
include: [ // 只会命中这里面的文件
path,resolve(__dirname,'app')
],
exclude: [ //忽略这里面的文件
path.resolve(__dirname,'app/demo-files')
],
use: [ //使用哪些loader,有先后次序,从后向前执行
'style-loader', //直接使用loader的名称
{
loader: 'css-loader',
options: { //向html-loader传递一些参数
}
}
]
},
],
noParse: [ //不用解析和处理的模块
/special-library\.js$/ //用正则匹配
],
},
4、插件(plugins):
plugins: [
new HtmlWebpackPlugin({template: './app/index.html'})
],
5、模式:
//通过选择 development 或 production 之中的一个,来设置 mode 参数
mode: 'production'
6、开发服务器:自动编译,自动打开浏览器,自动刷新浏览器
devServer: { // DevServer相关的配置
proxy: { // 代理到后端服务接口
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname,'public'), //配置 DevServer HTTP服务器的文件根目录
compress: true, //是否开启Gzip压缩
historyApiFallback: true, //是否开发 HTML5 History API 网页
hot: true, //是否开启模块热替换功能
https: false, // 是否开启 HTTPS 模式
},
6、resolve
resolve: {
modules: [ //寻找模块的根目录,为array类型,默认以 node_modules为根目录
‘node_modules’,
path.resolve(__dirname,‘app’)
],
extensions: [’.js’,’.json’,’.jsx’,’.css’], //模块的后缀名
alias: { //模块别名配置,用于映射模块
//将‘module’映射成‘new-module’,同样,‘module/path/file’也会被映射成‘new-module/path/file’
‘module’: ‘new-module’,
//使用结尾符号
后
,
将
‘
o
n
l
y
−
m
o
d
u
l
e
’
映
射
成
‘
n
e
w
−
m
o
d
u
l
e
’
,
/
/
但
是
不
像
上
面
的
,
‘
m
o
d
u
l
e
/
p
a
t
h
/
f
i
l
e
’
不
会
被
映
射
成
‘
n
e
w
−
m
o
d
u
l
e
/
p
a
t
h
/
f
i
l
e
’
′
o
n
l
y
−
m
o
s
u
l
e
s
后,将‘only-module’映射成‘new-module’, //但是不像上面的,‘module/path/file’不会 被映射成‘new-module/path/file’ 'only-mosules
后,将‘only−module’映射成‘new−module’,//但是不像上面的,‘module/path/file’不会被映射成‘new−module/path/file’′only−mosules’:‘new-module’,
},
alias: [ //alias还支持使用数组类更详细地进行配置
{
name: ‘module’, //老模块
alias: ‘new-module’, //新模块
// 是否只映射模块,如果是true,则只有‘module’会被映射;如果是false,则’module/inner/path’也会被映射
onlyModule: true
}
],
symlinks: true, //是否跟随文件的软连接去搜索模块的路径
descriptionFiles: [‘packsge.json’], // 模块的描述文件
mainFilelds: [‘main’], //模块的描述文件里描述入口的文件的字段名
enforceExtension: false, //是否强制导入语句写明文件后缀
},
7、performance
//输出文件的性能检查配置
performance: {
hints: ‘warning’, //有性能问题时的输出警告
hints: ‘error’, //有性能问题时输出错误
hints: false, // 关闭性能检查
maxAssetSize: 200000, //最大文件的大小(单位为bytes)
maxEntrypointSize: 400000, //最大入口文件的大小(单位为bytess)
assetFilter: function(assetFilename) {
return assetFilename.endsWith(’.css’) || assetFilename.endsWith(’.js’) ;
}
},
devtool: ‘source-map’, //配置source-map
context: __dirname, //webpack使用的根目录,string类型必须是绝对路径
// 配置输出代码的运行环境
target: ‘web’, //浏览器,默认
target: ‘webworker’, //WebWorker
target: ‘node’, //Node.js使用require
语句加载 Chunk代码
target: ‘async-node’, //Node.js异步加载 Chunk代码
target: ‘node-webkit’, // nw.js
target: ‘electron-main’, // electron,主线程
target: ‘electron-renderer’, // electron,渲染线程
externals: {
jquery: ‘jQuery’
},
status: { //控制台输出日志
assets: true,
colors: true,
errors: true,
errorDetails: true,
hash: true,
},
profile: true, //是否捕捉webpack构建的性能信息,用于分析是什么原因导致构建性能不佳
cache:fasle, // 是否启用缓存啦提升构建速度
watch: true, //是否开始
watchOptions: { // 监听模式选项
// 不监听的文件或文件夹,支持正则匹配。默认为空
ignored: /node_modules/,
// 监听到变化后,等300ms再执行,截流,防止文件更新太快导致重新编译频率太快,默认为300ms
aggregateTimeout: 300,
// 不停地询问系统指定的文件有没有发生变化,默认每秒询问1000次
poll: 1000
},