Webpack在生产环境中有一个重要的作用就是减少http的请求数,就是把多个文件打包到一个js里,这样请求数就可以减少好多
一、安装
1、先装好node和npm,因为webpack是一个基于node的项目。然后npm install -g webpack webpack-cli
全局安装webpack webpack-cli
2、新建项目文件夹,比如webpack_demo,然后新建一个package.json的文件在项目根目录下
npm init //询问一些问题:按回车选择默认值 自动生成文件package.json
npm i webpack webpack-cli--D //这行命令中, i 是 install 的缩写。 --D 是 --save-dev 的缩写。
(--save-dev作用是安装的插件的同时,将插件名写入package.json的devDependencies列表中)
目前是开发环境,所以需要加上-dev,用户运行不需要依赖这个包
如果用户运行需要依赖这个包,那么就不加-dev,直接是--save,保存到生产环境
需要补充的是,刚才输入的 --save-dev 的含义是:
①将所安装的包分类到开发模式下
②将安装过的包写入到 package.json 配置文件
至此,webpack安装完成
3、在项目根目录下,建立
项目目录:
./index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./dist/main.js"></script>
<!-- src引入的文件将在接下来由 webpack 打包创建 -->
</body>
</html>
./src/index.js:
import {name} from './init';//引入 init.js 存于 name , (js后缀可以省略)
alert(name);
./src/init.js:
var name = "newApp";
export {//ECMAScript 6 语法 , 向外暴露接口供其他文件调用时使用
name//将变量 name 指定为向外暴露成员
};
4、执行打包(直接打包,没有配置文件的情况下),上面多个文件文件执行打包:webpack
5、在package.json里面配置
可以在在package.json文件的"scripts"属性下增加了"build"属性,即
"build": "webpack --mode production --progress --display-modules --colors --display-reasons"
这样使用npm run build,即可执行webpack打包
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode deveplopment",
"build": "webpack --mode production"
}
就可以在命令行使用npm run dev执行打包操作了
不管有没有使用index.js,都会打包该文件放到main.js里面,这是没有配置文件的情况下,默认入口文件是index.js,如果没有创建index.js,那么打包就会报错
如果有配置文件,那么就严格按照配置文件配置的入口文件来
我们先创建src文件,还有一个dist文件,存放默认的打包生成的文件,然后在src里再创建index.js文件
这样就可以使用npm run dev进行打包了
6、总结:
7、webpack的一些相关命令
如果我们更改我们写的代码的时候,就需要重新进行打包,那就是更改一次又手动进行打包一次,那是很麻烦的,所以我们可以使用如下命令监听这个事件,源文件一更新,就会进行自动打包;一开始watch时关闭地,我需要将它打开:npx webpack --mode development --watch
注意: 这个命令只是单纯监听了默认的打包路径,也就是能监听到src下index.js的变化,也能够随将变化时进行保存刷新后其自动打包,但是,并不能监听到demo.js. 还有就是你的执行这个命令的时候,它必需属于一直监听的状态, 如果被停止了,那监听状态也停止.
二、下面介绍使用配置文件进行打包
1、创建webpack.config.js
举例:
const path = require('path');
module.exports = {
entry: './src/index.js', //入口文件的配置项
output: { //出口文件的配置项
path: path.resolve(__dirname, 'dist'), //dist目录所在的绝对路径
filename: 'main.js'
},
module: {//配置 loader 模块:例如解读CSS,图片如何转换,压缩
rules: [//相关规则写在这里
{
test: /\.css$/,//正则表达式:根据后缀为 .css 的文件来匹配 css 文件
use: [//匹配搭配 css 文件后,打包时使用以下 loader 来处理文件
{ loader: 'style-loader' },//loader 名称
{
loader: 'css-loader',//loader 名称
options: {
modules: true
}
}
]
}
]
},
plugins:[], //插件,用于生产模版和各项功能
mode: 'development' //打包模式,默认生产者模式,
devServer:{} //配置webpack开发服务功能
};
2、在当前目录下(package.json所在文件夹)执行:npx webpack,即可自动执行打包
3、各种参数说明:
4、如果入口文件有多个,如果output只定义一个出口文件,那么所有的入口文件都会被打包到这一个出口文件;如果想各自生成自己对应的出口文件,那么就得重新配置出口文件,如:
const path = require('path');
module.exports = {
entry:{
main:'./src/script/main.js',
a:'./src/script/a.js'
},
output: { //出口文件的配置项
path: path.resolve(__dirname, 'dist'), //dist目录所在的绝对路径
filename: '[name]-[hash]-[chunkhash].js' //[name]:名字和入口文件一样 【hash】:随机生成的本次打包的hash值 [chunkhash]:要打包文件的版本号,除非文件修改了,否则都是不变的
}
};
5、打包过后的文件名是变化的,那么在index.html中引入该文件,难道每次都需要修改路径名称吗,可以使用插件来自动生成:npm install html-webpack-plugin --save-dev
在webpack.config.js中
var htmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path');
module.exports = {
entry:{
main:'./src/script/main.js',
a:'./src/script/a.js'
},
output: { //出口文件的配置项
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name]-[hash]-[chunkhash].js' ,
publicPath:'static' //当项目需要上线时,加上这个,那么打包后生成的js文件,前面都会加上static,如:<script type="text/javascript" src="static/js/0e8f76480769da375fb2.js"></script></body>
},
plugins:[
new htmlWebpackPlugin({
template:'index.html', //以根目录下面的index.html为模板文件进行更新
filename:'index-[hash].index', //生成的html文件的名称包含hash值,自定义生成的html文件名,这样每次都会生成一个不同hash的 index文件,不建议这样使用,直接是index.html就好,默认就是index.html,可以不用设置
inject:'head', //打包后的js文件放置于头部,即</head>上面
title:'webpack is good', //设置html的title,在模板文件使用:<title><%= htmlWebpackPlugin.options.title %></title> 获取到
minify:{ //上线前压缩index.html文件
removeComments:true, //删除注释
collapseWhitespace:true //删除空格
}
})
]
};
这样,就在输出路径dist下,生成了index.html(以根目录下的index为模板),并且也把打包后的js文件引入进去了,全自动,在filename后面加上js/,这样就使得js文件都打包到dist/js目录下,而html文件是直接打包到dist目录下
6、loader,和plugin不同,是专门用来处理资源文件,如转es6,less、图片压缩、图片转base64等的处理
★转es6
首先安装babel:npm install -D babel-loader babel-core babel-preset-env
然后再package.json里面配置:
"babel":{
"presets": ["env"]
}
在webpack.config.js里面配置
let htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: "production",
entry: './src/index.js', //入口文件的配置项
output: { //出口文件的配置项 ,输出路径为dist目录,即所有文件都要打包到该目录下
path: path.resolve(__dirname, './dist'),
filename: 'js/bundle.js',
},
module: {//配置 loader 模块:例如解读CSS,图片如何转换,压缩
rules: [//相关规则写在这里
{
test: /\.js$/,//正则表达式:根据后缀为 .css 的文件来匹配 css 文件
loader:'babel-loader'
}
]
},
plugins:[
new htmlWebpackPlugin({
filename:'index.html',
template:'index.html'
})
], //插件,用于生产模版和各项功能
mode: 'development', //打包模式,默认生产者模式,
devServer:{} //配置webpack开发服务功能
};
★刚刚webpack打包提示错误:
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
解决:需要使用绝对路径。
Error: Cannot find module '@babel/core'
解决:babel-loader的版本不一样,之前的是@7.1.5版本,而现在是@8.0.0版本。所以卸载当前版本,重新安装之前的版本
★打包css文件
首先安装对应的loader,npm install style-loader css-loader --save-dev
webpack视所有资源都是一个模块,所有的资源文件都可以打包到webpack中,需要在入口文件import该资源文件
比如:入口文件是index.js,在里面 import './src/style.css'
配置webpack.config.js文件
module: {//配置 loader 模块:例如解读CSS,图片如何转换,压缩
rules: [//相关规则写在这里
{
test: /\.js$/,//正则表达式:根据后缀为 .js 的文件来匹配 js 文件
loader:'babel-loader'
},
{
test: /\.css$/,//正则表达式:根据后缀为 .css 的文件来匹配 css 文件
loader:'style-loader!css-loader!less-loader' //css-loader使得在js里面可以处理css文件,style-loader使得js处理完的样式插入到index.html页面中
}
]
},
★遇见一系列错误,以安装npm install babel-core@7.0.0-bridge.0 --save-dev结束,成功打包了css文件
★转换less文件 npm install less-loader --save-dev
创建app.less文件,在入口文件引入:import './app.less'
配置webpack.config.js文件
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader'
}
★打包图片文件 npm install file-loader --save-dev
1、在css文件中引入图片
配置webpack.config.js文件
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'file-loader' ,
query:{
name:'img/[hash].[ext]'
}
}
默认是打包到dist目录下,如果要想打包到dist/img下,可以添加query,如上所示。
【注意】要查看loader的用法,可以去https://www.npmjs.com/,搜索对应的loader查看用法
loader:'style-loader!css-loader!less-loader
loader的处理方式是从右到左,先处理less-loader,然后依次到左
★url-loader,可以处理图片和文件,当原始文件大小大于指定的值的时候,会交给file-loader处理,小于指定的值的时候,会转为base64位编码,不再是url了,而是一段编码
合理分配图片,是base64嵌入页面,还是通过http求求过来,http请求过来的图片可以缓存,base64编码不行
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'url-loader' ,
query:{
limit:20000, //即20k
name:'img/[hash].[ext]'
}
}
★img-webpack-loader,配合file-loader、url-loader一起使用,压缩通过http请求的图片大小
{
test:/\.(png|jpg|gif|svg)$/i,
loaders:[
'url-loader?limit=20000&name=img/[hash].[ext]',
'image-webpack-loader'
]
}
三、热更新
1、在webpack.config.js里面配置devServer
devServer:{
contentBase:path.resolve(__dirname,'dist') //基本目录结构,监听哪里的代码
host:'10.1.28.102', //ip地址,不建议填localhost 命令行ipconfig查看ipv4的值即是ip地址
compress:true, //服务器压缩参数,是否启用服务器压缩,一般启用
port:1717 //任何喜欢的数字
}
2、安装服务:npm install webpack-dev-server --save-dev
3、配置package.json
"scripts": {
"server": "webpack-dev-server",
},
4、运行命令:npm run server
注意:是conteneBase,不是contentPath
运行命令是npm run server,不是webpack-dev-server
四、live-server
本地开发常常需要搭建临时的服务,第一时间我们会想到用http-server。
但现在流行修改文件浏览器自动刷新hot socketing(热拔插),如live-reload。
若想浏览器自动打开项目,用opener。
现在live-server实现了三个插件的所有功能,并且很简单就能启动一个看起来很专业的本地服务
"scripts": {
"server": "live-server ./ --port=9090"
}
然后执行 npm run server
浏览器会自动打开,并且当你修改本地文件,浏览器都会立即同步
五、案例之打包css文件
1、模块:CSS文件打包Loaders
Loaders是Webpack最重要的功能之一,他也是Webpack如此盛行的原因。通过使用不同的Loader,Webpack可以利用脚本和工具,从而对不同的文件格式进行特定处理。
注意:所有的Loaders都需要在npm中单独进行安装,并在webpack.config.js里进行配置。
Loaders的配置参数:
2、打包css文件,
首先在src文件夹下,建立一个css文件夹,在文件夹下需要打包的css文件
css文件建立好后,需要引入到入口文件中,才可以打包到,这里我们引入到entry.js中。
style-loader:用来处理css文件中的url()等
安装:npm install style-loader --save-dev
css-loader:用来将css插入到页面的style标签
安装:npm install css-loader --save-dev
两个loader都下载安装好后,我们就可以配置我们loaders了。
修改webpack.config.js中module属性中的配置代码如下(三种写法):
第一种写法:直接用use。
module:{
rules:[
test:'/\.css$/',
use:['style-loader','css-loader']
]
}
第二种写法:把use换成loader。
module:{
rules:[
test:'/\.css$/',
loader:['style-loader','css-loader']
]
}
第三种写法:用use+loader的写法:
module:{
rules:[
{
test:/\.css$/,
use:[
{
loader:'style-loader'
},
{
loader:'css-loader'
}
]
}
]
}
9、插件配置:配置JS压缩
上线前,压缩js代码,通过使用插件的方式来实现
引入一个uglifyjs-webpack-plugin(JS压缩插件,简称uglify)。
注意:虽然uglifyjs是插件,但是webpack版本里默认已经集成,不需要再次安装,但是是需要引入的
在webpack.config.js里面引入
const uglify = require('uglifyjs-webpack-plugin');
引入后,在plugins配置里new一个uglify对象即可使用,
plugins:[ //注意是[],不是{}
new uglify() //后面不加分号,多个的话加逗号
]
最后,在终端命令行,使用webpack进行打包,压缩js文件
npm run server用在开发环境,启动服务器,是对代码进行预览的,此时的代码不需要压缩,否则无法调试
所以上面的开发完毕之后,使用下面的进行打包压缩,然后直接上线,不需要再进行热更新在调试什么的了
webpack是打包压缩,用于生产环境,打包压缩之后就上线了
webpack打包的时候发生错误:Error: Cannot find module 'uglifyjs-webpack-plugin'
执行即可npm install --save-dev html-webpack-plugin
在实际开发中,webpack配置文件是分开的,开发环境一个文件,生产环境一个文件
10、插件配置:HTML文件的发布
此时,将dist里面的index.html剪切到src目录下面,并去掉我们的JS引入代码(webpack会自动为我们引入JS),
<script src="./bundle.js" type="text/javascript" charset="utf-8"></script>
因为这才是我们真实工作的目录文件结构。
然后配置webpack.config.js文件
引入html-webpack-plugin插件
const htmlPlugin = require('html-webpack-plugin');
再进行安装该插件
npm install --save-dev html-webpack-plugin
在webpack.config.js文件,添加参数
plugins:[
new htmlPlugin({
minify:{
removeAttributeQuotes:true
},
hash:true,
template:'.src/index.html'
})
]
说明:
此时,完全不需要创建dist目录,dist目录下也不需要创建任何文件,全部webpack自动
index.html文件已经被打包到我们的dist目录下了,并且自动为我们引入了路口的JS文件。
执行完webpack之后,文件已经被打包压缩了,然后执行npm run server,即可在本地查看效果
11、图片迈坑:CSS中的图片处理
第一在src目录下新建一个images文件夹,把图片放入images文件夹
第二然后安装loader:file-loader url-loader
npm install --save-dev file-loader url-loader
file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。
第三使用loader,记得在loader使用时不需要用require引入,使用plugins才需要使用require引入。
module:{
rules:[
{
test:/\.(png|jpg|gif)/,
use:[{
loader:'url-loader',
options:{
limit:5000
}
}]
}
]
}
之所以只引入url-loader,是因为url-loader已经包含了file-loader的功能
12、图片迈坑:CSS分离与图片路径处理
12.1、把CSS从JavasScript代码中分离出来
第一安装extract-text-webpack-plugin插件
npm install --save-dev extract-text-webpack-plugin
第二在配置文件里引入
const extractTextPlugin = require(''extract-text-webpack-plugin);
第三在plugins配置文件里new一下
plugins:[
new extractTextPlugin('css/style.css'); //这里的css/style.css是分离后的路径位置,位于dist目录下
]
第四修改原来我们的style-loader和css-loader。
module:{
rules:[
{
test:/\.css$/,
use:extractTextPlugin.extract({
fallback:'style-loader',
use:'css-loader'
})
}
]
}
利用extract-text-webpack-plugin插件很轻松的就把CSS文件分离了出来,但是CSS路径并不正确
12.2图片路径问题
第一在webpack.config.js 上方声明一个对象,叫website。
var website ={
publicPath:"http://10.1.28.102:1717/"
}
第二在output选项中引用这个对象的publicPath属性。
//出口文件的配置项
output:{
//输出的路径,用了Node语法
path:path.resolve(__dirname,'dist'),
//输出的文件名称
filename:'[name].js',
publicPath:website.publicPath
}
第三使用webpack进行打包
如何把图片放到指定的文件夹下,如images下面
修改modules里面的图片url-loader选项
modules:{
rules:[
test:'\/.(png|jpg|gif)\',
options:{
limit:5000,
outputPath:'/images/'
}
]
}
13、图片迈坑:处理HTML中的图片
第一安装 html-withimg-loader
npm install --save-dev html-withimg-loader
第二配置webpack.config.js
{
test:'/\.(htm|html)$/i', //注意(htm|html)加括号
use:['html-withimg-loader']
}
14、给webpack增加babel支持
安装相关依赖包
npm c install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
在webpack.config.js里面进行配置
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
options:{
presets:[
"es2015","react"
]
}
},
exclude:/node_modules/
}
但是不建议直接在webpack.config.js中进行配置,而是把配置写在.babelrc文件里
在项目根目录新建.babelrc文件,并把配置options写到文件里。
.babelrc //json格式 presets-渲染器
{
"presets":["react","**es2015**"]
}
.webpack.config.js里的loader配置
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
},
exclude:/node_modules/ //不转node_modules里面的es6语法
}
ENV:
现在网络上已经不流行babel-preset-es2015,现在官方推荐使用的是babel-preset-env,那我们紧跟潮流
安装最新的env
npm n install --save-dev babel-preset-env
然后修改.babelrc里的配置文件。其实只要把之前的es2015换成env就可以了。
{
"presets":["react","env"]
}
15、打包后如何调试
调试只针对于开发环境
上线前,一定要删除devtool: 'eval-source-map',然后再进行打包,否则有安全隐患
个人意见是,如果大型项目可以使用source-map,如果是中小型项目使用eval-source-map就完全可以应对,需要强调说明的是,source map只适用于开发阶段,上线前记得修改这些调试设置。
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
}
}
16、实战技巧:开发和生产并行设置
依赖dependencies
开发环境
开发依赖devDependencies
生产环境 (上线环境)
生产依赖dependencies
npm install jquery //安装到全局环境,本项目下面是没有的,如果别人拷走了,那么拷走的文件里面是不包含jquery,可能会报错
npm install jquery --save,安装到本项目下面,并且写入dependencies
拿到别人的项目,比如从github上下载下来了一个新项目,首先需要npm install进行初始化安装
会搜索package.json,搜索里面的包进行安装。如果全局里面有相关的包,那么直接就从本机全局里面拷贝,不用下载
拿到别人的项目,比如从github上下载下来了一个新项目,首先需要npm install进行初始化安装,如果只安装生产环境的包,那么就是npm install --production,而不是npm install
☆☆☆☆配置生产和开发环境并行
webpack.config.js是存在于node环境中,都是用node命令运行
局部安装webpack npm install --save-dev-webpack,webpack被安装到了项目文件夹node_modules文件夹下面
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。