- 默认在终端执行 webpack 命令的时候,会在当前目录下找 ./src/index.js 这个文件作为入口文件,然后进行打包。
如果我们想指定入口文件和打包输出目录的话,就可以在终端输入
npx webpack --entry ./src/main.js --output-path ./build
// 入口文件为 ./src/main.js 打包输出目录为 ./build
命令行还可以添加哪些参数请到官方文档这里查阅。
- 通过命令行的方式添加这些 webpack 的配置参数可读性差,也很麻烦,所以最常见的方式是在项目根目录下新建
webpack.config.js
文件,然后在其中用 commonjs 的方式导出一个对象即可。
// webpack.config.js
const path = require('path')
module.exports = {
entry: './src/main.js', // 入口文件
output: { // 输出
filename: 'bundle.js',
path: path.resolve(__dirname, './build') // 必须是绝对路径
}
}
终端执行 webpack 命令的时候,默认会去找项目目录下的 webpack.config.js ,如果想要指定配置文件的名字,可以提供命令行参数:
webpack --config wk.config.js
- 事实上webpack在处理应用程序时,它会根据命令或者配置文件找到入口文件
- 从入口开始,会生成一个
依赖关系图
,这个依赖关系图会包含应用程序中所需的所有模块(比如.js文件、css文件、图片、字体等) - 然后
遍历图结构
,打包一个个模块(根据文件的不同使用不同的loader来解析)
当在 js 文件中引入了 css 文件后,使用 webpack 打包就会报错,这就是由于缺少 loader 去解析 css 文件。
- loader 可以用于对
模块的源代码
进行转换 - 我们可以将
css文件也看成是一个模块
,我们是通过import来加载这个模块
的 - 在加载这个模块时,
webpack其实并不知道如何对其进行加载
,我们必须制定对应的loader来完成这个功能 - css-loader 可以读取 css 文件
但是安装完 css-loader 打包后会报错,因为没有告诉 webpack 怎么去将 css-loader 和 css 文件去做关联。
css-loader 的使用方式有三种:
- 内联方式
内联方式使用较少,因为不方便管理;在引入的样式前加上使用的loader,并且使用!分割;
import 'css-loader!../css/style.css'
-
cli 方式(webpack 5 已经不再支持)
-
配置文件方式。
- module.rules中允许我们配置多个loader(因为我们也会继续使用其他的loader,来完成其他文件的加载);
- 这种方式可以更好的表示loader的配置,也方便后期的维护,同时也让你对各个Loader有一个全局的概览
module.rules的配置如下:
- rules属性对应的值是一个数组
[rule]
- 数组中存放的是一个个的Rule,Rule是一个对象,对象中可以设置多个属性:
- test属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;
- use属性:对应的值时一个数组:
[UseEntry]
- UseEntry是一个对象,可以通过对象的属性来设置一些其他属性
- loader:必须有一个 loader属性,对应的值是一个字符串;
- options:可选的属性,值是一个字符串或者对象,值会被传入到loader中;
- query:目前已经使用options来替代
- 传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ])
- UseEntry是一个对象,可以通过对象的属性来设置一些其他属性
- loader属性: Rule.use: [ { loader } ] 的简写。
module: {
rules: [
{
// 规则使用正则表达式
test: /\.css$/, // 匹配资源
use: [
// { loader: "css-loader" },
// 注意: 编写顺序(从下往上, 从右往做, 从后往前)
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
"postcss-loader"
],
// loader: "css-loader"
}
]
}
下面看看三种写 loader 的方式:
// 最完整的写法
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'css-loader'
}
]
}
]
}
// 简写法
module: {
rules: [
{
test: /\.css$/,
use: [
"css-loader"
]
}
]
}
// 简写法
module: {
rules: [
{
test: /\.css$/,
loader: "css-loader"
}
]
}
css-loader 处理 css 后打包不报错了,但是发现打包后的代码并没有使 css 生效,因为 css-loader 只解析 css 文件,并不会将 css 插入页面。想要插入样式,需要用到 style-loader。
如果使用了 css 预处理器编写样式,例如 less,就需要先按照 less 工具,然后安装 less-loader,less-loader 会调用 less 工具先将 less 文件编译成 css 文件,然后再执行后续 css-loader 和 style-loader 的操作。
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
针对不同浏览器对 css 和 js 支持不同特性的情况,我们需要做兼容性处理。
浏览器市场占有率是在https://www.caniuse.com/usage-table这里查的。
我们需要为项目配置 browserslist,来告诉各种工具需要匹配哪些版本的浏览器。
Browserslist是什么?Browserslist是一个在不同的前端工具之间,共享目标浏览器和Node.js版本的配置:
- Autoprefixer
- Babel
- postcss-preset-env
- eslint-plugin-compat
- stylelint-no-unsupported-browser-features
- postcss-normalize
- obsolete-webpack-plugin
> 1%
last 2 versions
not dead
类似这样的配置使用的是caniuse-lite的工具来查询匹配的浏览器的,这个工具的数据来自于caniuse的网站上。
-
defaults:Browserslist的默认浏览器(> 0.5%, last 2 versions, Firefox ESR, not dead)。
-
5%:通过全局使用情况统计信息选择的浏览器版本。>=,<和<=工作过。
- 5% in US:使用美国使用情况统计信息。它接受两个字母的国家/地区代码。
> 5%
in alt-AS:使用亚洲地区使用情况统计信息。有关所有区域代码的列表,请参见caniuse-lite/data/regions> 5%
in my stats:使用自定义用法数据。> 5%
in browserslist-config-mycompany stats:使用来自的自定义使用情况数据browserslist-config-mycompany/browserslist-stats.json。- cover 99.5%:提供覆盖率的最受欢迎的浏览器。
- cover 99.5% in US:与上述相同,但国家/地区代码由两个字母组成。
- cover 99.5% in my stats:使用自定义用法数据。
-
dead:24个月内没有官方支持或更新的浏览器。现在是IE 10,IE_Mob 11,BlackBerry 10,BlackBerry 7, Samsung 4和OperaMobile 12.1。
-
last 2 versions:每个浏览器的最后2个版本。
- last 2 Chrome versions:最近2个版本的Chrome浏览器。
- last 2 major versions或last 2 iOS major versions:最近2个主要版本的所有次要/补丁版本。
-
node 10和node 10.4:选择最新的Node.js10.x.x 或10.4.x版本。
-
current node:Browserslist现在使用的Node.js版本。
-
maintained node versions:所有Node.js版本,仍由Node.js Foundation维护。
-
iOS 7:直接使用iOS浏览器版本7。
- Firefox > 20:Firefox的版本高于20 >=,<并且<=也可以使用。它也可以与Node.js一起使用。
- ie 6-8:选择一个包含范围的版本。
- Firefox ESR:最新的[Firefox ESR]版本。
- PhantomJS 2.1和PhantomJS 1.9:选择类似于PhantomJS运行时的Safari版本。
-
extends browserslist-config-mycompany:从browserslist-config-mycompanynpm包中查询。
-
supports es6-module:支持特定功能的浏览器。es6-module这是“我可以使用” 页面feat的URL上的参数。有关所有可用功能的列表,请参见。caniuselite/ data/features
-
browserslist config:在Browserslist配置中定义的浏览器。在差异服务中很有用,可用于修改用户的配置,例如browserslist config and supports es6-module。
-
since 2015或last 2 years:自2015年以来发布的所有版本(since 2015-03以及since 2015-03-10)。
-
unreleased versions或unreleased Chrome versions:Alpha和Beta版本。
-
not ie <= 8:排除先前查询选择的浏览器。
可以使用命令行查询某些条件对应的浏览器版本
npx browserslist ">1%, last 2 version, not dead"
and_chr 89
and_ff 86
and_qq 10.4
and_uc 12.12
android 89
baidu 7.12
chrome 89
chrome 88
edge 89
edge 88
firefox 87
firefox 86
ie 11
ios_saf 14.0-14.5
ios_saf 13.4-13.7
kaios 2.5
op_mini all
op_mob 62
opera 73
opera 72
safari 14
safari 13.1
samsung 13.0
samsung 12.0
有两种方法配置 browserslist
- 在 package.json 中配置
browserslist: [
'> 1%',
'last 2 versions',
'not dead',
]
- 在 browserslistrc 文件中配置
> 1%
last 2 versions
not dead
如果没有配置,会有一个默认配置:
> 0.5%,
last 2 versions,
Firefox ESR,
not dead
每一行规则之间是 or 或 的关系,如果要使用 and 关系,就写到一行里使用 and 连接。not 取反。
> 0.5% and last 2 versions
not dead
- 什么是PostCSS呢?
- PostCSS是一个通过JavaScript来转换样式的工具;
- 这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置;
- 但是实现这些工具,我们需要借助于PostCSS对应的插件;
- 如何使用PostCSS呢?主要就是两个步骤:
- 第一步:查找PostCSS在构建工具中的扩展,比如webpack中的postcss-loader;
- 第二步:选择可以添加你需要的PostCSS相关的插件;
当然,我们能不能也直接在终端使用PostCSS呢?也是可以的,但是我们需要单独安装一个工具postcss-cli;
- 我们可以安装一下它们:postcss、postcss-cli
npm install postcss postcss-cli -D
- 我们编写一个需要添加前缀的css:
- https://autoprefixer.github.io/
- 我们可以在上面的网站中查询一些添加css属性的样式;
.content {
/* 十六进制通常是写几位 */
color: #12345678;
}
:fullscreen {
}
.content {
user-select: none;
transition: all 2s ease;
}
- 因为我们需要添加前缀,所以要安装autoprefixer:
npm install autoprefixer -D
- 直接使用使用postcss工具,并且制定使用autoprefixer
npx postcss --use autoprefixer -o end.css ./src/css/style.css
转化之后的css样式如下:
.content {
/* 十六进制通常是写几位 */
color: #12345678;
}
:-webkit-full-screen {
color: red;
}
:-ms-fullscreen {
color: red;
}
:fullscreen {
color: red;
}
.content {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
transition: all 2s ease;
}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9jc3MvdGVzdC5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxlQUFlO0VBQ2YsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsVUFBVTtBQUNaOztBQUZBO0VBQ0UsVUFBVTtBQUNaOztBQUZBO0VBQ0UsVUFBVTtBQUNaOztBQUVBO0VBQ0UseUJBQWlCO0tBQWpCLHNCQUFpQjtNQUFqQixxQkFBaUI7VUFBakIsaUJBQWlCO0VBQ2pCLHVCQUF1QjtBQUN6QiIsImZpbGUiOiJlbmQuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLmNvbnRlbnQge1xyXG4gIC8qIOWNgeWFrei/m+WItumAmuW4uOaYr+WGmeWHoOS9jSAqL1xyXG4gIGNvbG9yOiAjMTIzNDU2Nzg7XHJcbn1cclxuXHJcbjpmdWxsc2NyZWVuIHtcclxuICBjb2xvcjogcmVkO1xyXG59XHJcblxyXG4uY29udGVudCB7XHJcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgdHJhbnNpdGlvbjogYWxsIDJzIGVhc2U7XHJcbn1cclxuXHJcblxyXG4iXX0= */
因为postcss需要有对应的插件才会起效果,所以我们需要配置它的plugin
module: {
rules: [
{
// 规则使用正则表达式
test: /\.css$/, // 匹配资源
use: [
// { loader: "css-loader" },
// 注意: 编写顺序(从下往上, 从右往做, 从后往前)
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
require('autoprefixer')
]
}
}
}
],
// loader: "css-loader"
},
]
}
事实上,在配置postcss-loader时,我们配置插件并不需要使用autoprefixer。我们可以使用另外一个插件:postcss-preset-env。postcss-preset-env也是一个postcss的插件;它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境添加所需的polyfill;也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer);
举一个例子:
- 我们这里在使用十六进制的颜色时设置了8位;
- 但是某些浏览器可能不认识这种语法,我们最好可以转成RGBA的形式;
- 但是autoprefixer是不会帮助我们转换的;
- 而postcss-preset-env就可以完成这样的功能;
npm install postcss-preset-env -D
使用 postcss-preset-env 插件来处理:
module: {
rules: [
{
// 规则使用正则表达式
test: /\.css$/, // 匹配资源
use: [
// { loader: "css-loader" },
// 注意: 编写顺序(从下往上, 从右往做, 从后往前)
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
require('postcss-preset-env'),
// 'postcss-preset-env' 简写
]
}
}
}
],
// loader: "css-loader"
},
]
}
如果 /\.css$/
和 /\.less$/
都需要设置同样的 postcss 设置,那么可以提取成根目录文件 postcss.config.js
module.exports = {
plugins: [
'postcss-preset-env'
]
}
使用 postcss-preset-env 后, css 被做了兼容性处理:
.content {
/* 十六进制通常是写几位 */
color: rgba(18,52,86,0.47059);
}
:-webkit-full-screen {
color: red;
}
:-ms-fullscreen {
color: red;
}
:fullscreen {
color: red;
}
.content {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
transition: all 2s ease;
}
postcss-preset-env 是含有 autoprefixer 的效果的,所以就不需要 autoprefixer 了。
注意:当使用 @import 语法在一个 css 文件中引入另外一个 css 文件时,如果首先由 postcss-loader 处理了第一个文件,当走到 @import 引入的文件时,默认将不再使用 postcss-loader 处理,而继续使用之后的 loader 处理,如果碰到 @import 时想让 loader 处理从头再来一次,需要像下面这样写:
use: [
// { loader: "css-loader" },
// 注意: 编写顺序(从下往上, 从右往做, 从后往前)
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
"postcss-loader"
],
importLoaders 是 css-loader 的一个属性, 用于配置 css-loader 作用于 @import 的资源之前有多少个 loader 。