说明
- 源代码
- 本篇主要对发布环境的配置说明
- 前面2点是对webpack的一个复习.
- 第3点开始,逐步配置部署代码
1. Webpack发布的策略
2.1 在实际开发中,一般会有两套方案:
- 开发期间的项目:包含了测试文件、测试数据、开发工具、测试工具等相关配置,有利于项目的开发和测试,但是这些文件仅用于开发,发布项目的时候需要删除
- 部署期间的项目,剔除了那些客户用不到的测试数据、测试工具和文件,比较纯净,减少了项目发布后的体积,有利于开发和部署
2.2 生产环境的配置文件
-
为了满足我们的发布策略,需要新建一个配置文件,命名为
webpack.publish.config.js
,将webpack.config.js
的配置拷贝过去,剔除一些开发配置项即可. -
将
devSever
节点删掉:
devServer: {
hot: true,
open: true,
port: 4321
}
- 将
plugins
节点下的热更新插件删掉:
new webpack.HotModuleRupluComuntPlugin()
2. Webpack从0开始使用
2.1 项目初始化
注: 使用的node版本是 12.10.0
2.1.1 新建项目(文件夹)webpack-senior
2.1.2 进入webpack-senior
新建下面三个:
- 打包之后的文件夹:
dist
- 项目的源代码:
src
- webpack的配置文件:
webpack.config.js
2.1.3 初始化项目
npm init -y
- 使用yarn安装 jquery:
yarn add jquery
(等同于 npm i -D jquery)
2.1.4 src的初始化
- 在其中新建如下文件和内容:
src/index.js
<html> <body> <ul> <li>这是第1个li</li> <li>这是第2个li</li> <li>这是第3个li</li> <li>这是第4个li</li> </ul> </body> </html>
src/main.js
import $ from 'jquery' $(function(){ $('li:odd').css('backgroundColor','pink'); $('li:even').css('backgroundColor','marron'); })();
2.1.5 配置文件的编写
-
上面完成了简单的页面和js对页面的操作,下面写Webpack的配置文件(webpack使用配置文件对项目进行打包构建)
-
webpack.config.js
const path = require('path'); module.exports = { entry: path.join(__dirname, './src/main.js'), output: { path: path.join(__dirname, './dist'), filename: 'bundle.js' } }
- 以上代码指明了webpack的入口和打包文件,下面需要装2个插件来使index.html和main.js在内存中生成:
yarn add webpack --dev
(webpack是在开发环境中进行的,因此需要在npm中使用-S,在yarn中则变为 --dev)yarn add webpack-dev-server html-webpack-plugin --dev
: 安装在内存中生成index.html和main.js的插件,改写webpack.config.js
如下:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, './src/main.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
plugin: [
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'),
filename: 'index.html'
})
]
}
- 上面已经将html页面放到了内存中,接下来配置启动命令:
package.json
{
"scripts": {
"dev": "webpack-dev-server --open --port 3000 hot"
}
}
2.1.6 小检测点
对上面过程进行说明:
- 从启动命令
npm run dev
说起 - 当在命令行,输入
npm run dev
时 - 工具:
webpack-cli
(安装在开发环境, yarn add webpack-cli --dev),会以命令行启动的目录作为当前目录,去寻找package.json
文件 - 找到
package.json
文件后,会寻找"scripts"
- 找到
scripts
对象后,进而找到"dev" - 然后运行命令
webpack-dev-server --open --port 3000 --hot
webpack-dev-server
:- 每次写完代码手动调用webpack去打包代码太麻烦,因此使用 webpack-dev-server来进行自动打包构建
- 会根据
package.json
中output的配置,生产一个内存中的main.js
文件.
2.2 webpack中loader的配置
webpack默认只能解析.js
和.json
文件,若想解析其他类型的文件,需要配置loader
配置loader解析.scss
- 在src目录下新建目录结构
/src/css/index.scss
- 在
index.scss
中写入如下:
html,
body {
margin: 0;
padding: 0;
ul {
list-style: none;
padding: 0;
margin: 0;
}
li{
font-size:12px;
line-height: 30px;
padding-left: 10px;
}
.box {
width: 500px;
height: 230px;
background: url('../images/开心.gif');
background-size: cover;
}
}
- 在
/src/index.html
中添加如下:
<div class="box"></div>
- 在main.js中导入
index.scss
:
import './css/index.scss';
此时项目肯定启动不了,因为未配置loader的webpack不能解析.scss
,下配置:
- 解析CSS、SCSS、URL加载
- 安装依赖:
yarn add style-loader css-loader sass-loader node-sass url-loader file-loader --dev
// webpack.config.js
module.exports = {
module:{
rules:[
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
{ test: /\.(png|gif|bump|jpg)$/, use: ['url-loader?limit=5000']}
]
}
}
- 解析ES6的高级语法
- 安装依赖:
yarn add babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 --dev
// webpack.config.js
module.exports ={
module:{
rules:[
{ test:/\.js$/, use:'babel-loader', exclude: /node_modules/ }
]
}
}
````
````js
// .babelrc
{
"presets": ["env", "stage-0"],
"plugins": ["transform-runtime"]
}
Error: Cannot find module '@babel/core'
: 查看报错,是因为babel-loader
的版本过高,根据提示输入yarn add babel-loader@7 --dev
即可Module not found: Error: Can't resolve 'scss-loader' in 'D:\L-rn\HeiMa\webpack-senior'
:没有找到scss-loader
模块,打开package.json可以看到,里面有一个’sass-loader’,将webpack.config.js
中的scss改为sass即可.
3. 使用Webpack打包项目
现在假设项目已经开发完毕,并且打算使用webpack将项目进行打包.
3.1 直接在命令行输入webpack
命令进行打包
- 直接打包,生成的项目体积会很大,许多不需要的内容都会被打包在里面
3.2 优化打包
3.2.1 新建一个打包时的webpack配置文件:
webpack.pub.config.js
3.2. 2 新建一个打包指令:
package.json
{
"scripts": {
"build": "webpack --config webpack.pub.config.js"
}
}
3.3.3 统一管理打包后的图片
- 将打包后的所有图片放到
dist/images
中统一管理 - 改变
webpack.pub.config.js
module.exports ={
module: {
rules:[
{ test:/\.(png|gif|bump|jpg)$/, use: ['url-loader?limit=5000&name=images/[hash:8]-[name].[ext]']}
]
}
}
3.3.4 清除之前的打包文件
- 每次打包都删除之前的dist文件
- 安装插件
yarn add clean-webpack-plugin --dev
- 配置:
webpack.pub.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
- TypeError: cleanWebpackPlugin is not a constructor : 规则配置的时候出错,不需要传入参数下面是官网原话,拿出组件时,用到了结构赋值.
By default, this plugin will remove all files inside webpack`s output.path directory,as well as all unused webpack assets after every successful rebuild
3.3.5 将自己的代码和第三方包分离
webpack.pub.config.js
const webpack = require('webpack');
const WebpackPlugin = new webpack.optimize.CommonsChunkPlugin({
name:'common',
filename: 'common.js'
});
module.exports = {
entry: {
app: path.join(__dirname, './src/main.js'),
common: ['jquery']
},
plugins:[
WebpackPlugin
]
}
- 自动优先加载第三方模块,在加载自己的代码.
3.3.6 将所有js文件放到js文件夹下面
- webpack.pub.config.js
const WebpackPlugin = new webpack.optimize.CommonsChunkPlugin({
name: 'common',
- filename: 'common.js'
+ filename: 'js/common.js'
});
module.exports = {
output: {
- filename:'[name].js'
+ filename:'js/[name].js'
}
}
3.3.7 压缩js代码
// 压缩JS代码
const UglifyJsPlugin = new webpack.optimize.UgliJsPlugin({
compress:{
warnings: false
}
});
// 定义生产环境,进一步压缩代码
const DefinePlugin = new webpack.DefinePlugin({
'process.env.NODE_ENV': 'production'
});
module.exports = {
plugins:[
UglifyJsPlugin,
DefinePlugin
]
}
3.3.8 压缩HTML代码
- webpack.config.js
const HtmlPlugin = new HtmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'),
filename: 'index.html',
minify:{
// 合并多余的空格
collapseWhitespace: true,
// 移除注释
removeComments: true,
// 移出属性上的双引号
removeAttributeQuotes: true
}
});
- 更多minify参数: 官方github
3.3.9 将css代码从js中抽离出来放在同一个文件夹下
- 官网
yarn add extract-text-webpack-plugin --dev
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin("style.css")
]
}
- 报错
Module build failed: CssSyntaxError
: 注释掉css的配置文件如下
module.exports = {
module: {
rules[
// {
// test: /\.css$/,
// use: ExtractTextPlugin.extract({
// fallback: "style-loader",
// use: "css-loader"
// })
// }
...
]
}
}
3.3.10 抽离css时候,图片路径问题
- 我们希望将CSS从js代码中抽出,单独存放在一个css文件夹下面.
- 如果css中使用到了url属性(如
{background: url(path)}
),在抽离出来后路径会发生变化. - 需要在抽离后,自动添加路径如下:
````git
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader'],
+ publicPath: '../'
})
}
````
3.3.11 压缩css文件
yarn add optimize-css-assets-webpack-plugin --dev
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
plugins: [
new OptimizeCssAssetsPlugin()
]
TypeError: Cannot read property 'compilation' of undefined
: 版本问题:yarn add [email protected] --dev
4.检测点
4.1 webpack是如何提高开发效率的
- 从文件中打开
.html
文件时,首先从磁盘上加载该文件的内容到内存中,然后在进行渲染 - 磁盘和内存的交互,远远没有内存中直接操作快
html-webpack-plugin
: 会根据给定的模板文件,生成在内存中的主页webpack-dev-server
: 会根据配置,生成一个在内存中的主入口函数- 优点是把能在内存中操作的部分,都放到内存中操作.缺点比较占用内存.
- 在开发阶段,可以很方便的使用第三方库,在生产阶段,可以使用一些插件将第三方库和源代码进行分离,并压缩代码
4.2 yarn和npm的命令行在使用的时候有什么区别.
- 首先理解
开发环境
和生产环境
开发环境
: 即开发过程中使用到的依赖,在npm中常常使用-D
来将依赖添加到开发环境(“devDependencies”)中生产环境
: 项目部署到服务器上所用到的依赖,在npm中常常使用-S
来讲依赖添加到生产环境(“dependencies”)中- 在yarn中,使用
yarn add
默认将包放在生产环境中,即对应npm的-S
- 若需要添加到开发环境中,则需要使用
yarn add [packagename] --dev
4.3 webpack中loader和plugins的区别
- 原生的webpack只能理解javascript和json文件,如果遇到如.css或.jsx这类的后缀名,是无法解析的,这个时候就需要用到loader了,而某些loader无法解析的,就用到plugins.
- loader是在开发过程用到的插件,而plugin贯彻整个开发和项目部署