使用CRM方法搞webpack,C(copy)、R(run)与M(modify);
目标一:实现转译Js
- 1.打开官网:webpack.js.org/guides/gett… 看启动步骤
- 2.
npm install webpack webpack-cli --save-dev
安装webpck 与 webpack-cli,上个命令时本地安装webpack与webpack-cli,安装后如果要查看版本号不能直接使用webpack --version
命令,需要找到其在本项目的安装目录再使用命令./node_modules/.bin/webpack --version
;这样需要打很多字,可以使用npx webpack --version
代替; - npx 想要解决的主要问题,就是调用项目内部安装的模块。npx 的原理很简单,就是运行的时候,会到node_modules/.bin路径和环境变量path里面,检查命令是否存在。由于 npx 会检查环境变量path,所以系统命令也可以调用。
- 运行webpacck
npx webpack
,以下就是目录结构


- 控制台出现了警告
- 为了解决这个警告,我们打开官网,新建一个js文件webpack.config.js,

- 这是mode为'development'模式,编译打包后的main.js代码是如下样子

- 如果mode为''production'模式,main.js代码是下面样子

目标二:理解文件中hash的用途
- 1.按照官方文档设置入口文件与出口文件,运行后报如下错误

src/index.js


- 我们把出口的js文件名字改为main.js,并且把原来的dist目录删掉,因为怕生成的新的与旧的分不清楚;




- 一般为了防止浏览器缓存,我们会在文件后面加hash值,那webpack是如何加的呢,请看下面的配置

- 下面我们讲解下http缓存的问题
定义:当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。这样带来的好处有:缓解服务器端压力,提升性能(获取资源的耗时更短了)。对于网站来说,缓存是达到高性能的重要组成部分。
HTTP/1.1定义的 Cache-Control 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。
1. 没有缓存:Cache-Control: no-store
2.缓存但重新验证Cache-Control: no-cache
每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。
- 过期:过期机制中,最重要的指令是 "max-age=",表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改;
Cache-Control: max-age=31536000
- 那怎么更新已经缓存的文件内容呢,由于http是根据文件名称来缓存的,因此我们可以只改变文件名称就可以了,也就是我们上次的增加Hash值;
- 请注意:首页是一定不能缓存的
当我们修改文件内容,每次打包都会生成一个新的带有hash的文件,这会出现很多老的文件,那我们应该怎么办呢?
- 我们可以在package.json里面的scripts增加一个命令:
"build": "rm -rf dist; webpack"
- 在控制台输入
npm run build

目标三:在webpack自动生成html
- 在官网搜索关键字“create html”,进入此网站https://webpack.js.org/plugins/html-webpack-plugin/#root
npm install --save-dev html-webpack-plugin
安装html-webpack插件 运行后,dist文件夹多了个html文件,里面自动连接了打包后的js

- 但是现在的html对我们来说没有用处,因为我们想定制自己的html,可用下面的配置

目标四:引入css
- 新增一个css文件,并在js中引入css


npm install --save-dev css-loader
安装 css-loader 与style-loader

使用webpack-dev-server
- webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)

- 运行
npm install --save-dev webpack-dev-server
- 其他配置https://www.webpackjs.com/guides/development/ 看这个网址的配置
- 需要注意的是:这个工具的用途是当你改代码不需要重新build,也不需要删除之前的代码,并不是帮我们生成dist目录,而是在内存搞定,读取我们的src/index.js,转换成可以运行的代码,然后放入内存中,而不是硬盘,因为硬盘太慢了,这样开发速度就加快了。
目标五:webpack引入css,并抽成文件
- 搜索‘webpack css extract plugin’
- 运行
sudo npm install mini-css-extract-plugin -D


挑战五:不同的环境访问不同的webpack-config文件
- 配置package.json

- 新建生成所用的配置文件
- 配置webpack,开发所用的配置文件,开发的时候,css是直接写入header里面
- 配置生成webpack,css以链接的方式


- 但是上面代码会遇到一个问题,两个配置文件有很多重复一样的代码,我可以使用继承的思想,提取公共的代码;新建一个名字为webpack.config.base.js的文件
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'index.[contenthash].js'
},
plugins: [new HtmlWebpackPlugin({
template:'./src/index.html'
})],
module: {
rules: [
],
}
}
webpack.config.js 的代码如下
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let base = require("./webpack.config.base");
module.exports = {
...base,
mode:'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
}
}
webpack.config.prod.js 的代码如下
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
let base = require("./webpack.config.base");
module.exports = {
...base,
mode:'production',
plugins: [
...base.plugins,
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
}),],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
}
}
运行正常
webpack loader 与webpack plugin的区别是什么?
- 翻译:loader是加载器,plugin是插件
- 解释加例子:加载器就是加载文件,比如babel-loader是用来加载js,style-loader是用来加载css;插件是用来扩展webpack功能的,比如htmlwebpackPlugin用来生成html文件;
目标六:引入scss
npm install sass-loader dart-sass webpack --save-dev
主要不要安装node-sass,而是sass-loader webpack.config.base.js新增如下配置
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader" // 将 JS 字符串生成为 style 节点
}, {
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader", // 将 Sass 编译成 CSS
options: {implementation:require('dart-sass')}
}]
}]
}
webpack.config.js 的代码如下
module: {
rules: [
...base.module.rules,
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
}
webpack.config.prod.js 的代码如下
module: {
rules: [
...base.module.rules,
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
}
新增一个scss文件,并在index.js中引入


目标七:引入less与stylus
npm install --save-dev less-loader less stylus-loader stylus
- base配置文件内容
module: {
rules: [{
test: /\.scss$/,
use: [{
loader: "style-loader" // 将 JS 字符串生成为 style 节点
}, {
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
}, {
loader: "sass-loader", // 将 Sass 编译成 CSS
options: {implementation:require('dart-sass')}
}]
},
{
test: /\.styl$/,
use: ['style-loader','css-loader','stylus-loader']
},
{
test: /\.less$/,
use: ['style-loader','css-loader','less-loader']
}
]
}
目标八:引入图片
- 使用file-loader,可把文件变为文件路径
目标九:实现懒加载 import()函数
- import()方法使用了promise式的回调,获取加载的包,这个功能可以实现按需加载我们的代码