目标一:用webpack编译JS
首先下载webpack
然后由于是本地安装,所以需要指定在哪里去找webpack的执行程序
./node_modules/.bin/webpack --version
还有一种简易的方法,就是
npx webpack
npx 会自动帮我们找webpack在本地的哪个地方
当我们运行之后,
会发现多了一个dist文件,里面还有main.js 这就是转译index.js的结果
转译JS初体验
在index.js里写一些浏览器里不能直接用的ES6语法, 再用webpack转译,看能否使用
// index.js
import x from './x.js'
console.log(x)
// x.js
export default 'xxxxx'
转译后的main.js:
也就是说webpack 敏锐地发现了其实我们的目标就是要打印'xxxxx'这个字符串
加上webpack的配置文件
webpack.config.js
const path = require('path');
module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
}
}
目标二:理解文件名中hash的用途
小知识点:HTTP响应头里的Cache-Control
HTTP缓存的作用
内容哈希就是每次修改之后,会生成一次新的哈希值,所以文件名会变化
所以: 如果内容不更新,就一直缓存,如果更新,就用新的文件名重新发送请求
加一个哈希值就相当于给文件加了一个版本号
所以文件名中hash的用途就是便于增加缓存
同时,由于每次重新执行webpack, 都会生成一个js文件,所以为了不占用过多内存,我们每次执行时,应该先删除现有的dist文件夹,再执行
于是要配置一下package.json
"scripts": {
"build": "rm -rf dist && webpack", // 就是这一句
"test": "echo "Error: no test specified" && exit 1"
},
以后每次 yarn build , 就会执行"rm -rf dist && webpack", 即先删除,再重新编译
目标三 用webpack生成html
安装
yarn add --dev html-webpack-plugin
再yarn build 就会自动生成一个index.html
此时的webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
plugins: [new HtmlWebpackPlugin({
title: 'My App',
template: "src/assets/index.html"
})]
}
以上代码是说按照 "src/assets/index.html" 为模板,title为MY APP生成一个网页
src/assets/index.html:
<!doctype html>
<html lang="ch-ZN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
// 根据配置里的title生成 title
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
目标四 用webpack 引入CSS
直接引入CSS报错:
说需要一个css loader
下载即可
yarn build --dev css-loader
yarn build --dev style-loader
再修改配置文件
webpack.config.js
module: {
rules: [
{
test: /.css$/i,
use: ['style-loader', 'css-loader']
}
]
}
然后再yarn build
然后如果引入css, webpack 就会把css标签读出来放到style标签里
红色圈中的就是加载的css
现在我们把css放进了style标签
但如果我们希望单独抽成css文件呢?
下载插件:
yarn add --dev mini-css-extract-plugin
添加配置:
目标五:简化编译
每次修改css, 首先是在dist文件夹里 http-server -c-1 开启服务器,如果要修改,就要断掉服务器,然后再改css, 再重新yarn build, 太麻烦了。
所以我们想要简化这一过程,需要用到webpack-dev-server
首先安装
yarn add --dev webpack-dev-server
配置方法:
然后每次启动从yarn build, 改成 yarn start
这样每次运行后,就会自动打开浏览器
目标六:根据模式选择不同的编译
目标:开发模式下,把css生成为style标签
在生产production模式下,把css单独抽成文件
在开发时,我们用yarn start,
在生产时,我们用yarn build,css生成style标签
我们能不能配两个config文件,实现这种需求
package.json
"scripts": {
// 这里指定webpack.config.prod.js的路径,参数是--config
"build": "rm -rf dist && webpack --config webpack.config.prod.js",
"start": "webpack-dev-server --open",
"test": "echo "Error: no test specified" && exit 1"
},
webpack.config.js
module: {
rules: [
{
test: /.css$/i,
// 下面这行表示生成style标签
use: ['style-loader', 'css-loader']
},
}
webpack.config.prod.js
module: {
rules: [
{
test: /.css$/i,
// 下面这行表示生成css文件
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
但是问题是,这两个文件只有少数几行不一样,其他都完全一样,有没有更好的办法?
有!使用JS的继承思想
首先我们准备一个webpack.config.base.js 把所有的公共属性都放进去
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
plugins: [new HtmlWebpackPlugin({
title: 'My App',
template: "src/assets/index.html"
})
],
module: {
rules: [
{
test: /.js$/i,
enforce: 'pre',
use: ['source-map-loader'],
},
]
}
}
然后webpack.config.js 和 webpack.config.prod.js分别继承这个base.js
首先引入,然后用...base即可引入Base的所有属性
有一个点需要注意:
如果是不希望全部覆盖掉base里的东西,而是希望继承一部分,修改一部分,可以在属性内部...base.module.rules
module: {
rules: [
// 先继承需要的
...base.module.rules,
// 再叠加我自己的, 这样就不会用我自己的这个配置覆盖掉之前的所有配置
{
test: /.js$/i,
enforce: 'pre',
use: ['source-map-loader'],
},
]
}
最终修改好的配置文件分别是:
webpack.config.js
// 引入Base
const base = require('./webpack.config.base')
module.exports = {
...base, // 把所有的base里的配置都加载进来
mode: "development",
module: {
rules: [
{
test: /.css$/i,
use: ['style-loader', 'css-loader']
}
]
}
}
webpack.config.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 引入Base
const 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: [
// 先继承需要的
...base.module.rules,
// 再叠加我自己的, 这样就不会用我自己的这个配置覆盖掉之前的所有配置
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
}
}
本文为fjl的原创文章,著作权归本人和饥人谷所有,转载务必注明来源