webpack的理解,webpack 核心
Webpack是前端资源构建工具,静态模块打包器;Webpack有五个核心概念(入口、输出、加载器、插件和模式)。下面就来深入看看这篇文章,希望能帮到你!
webpack 五个核心概念
1. Entry
条目指示webpack从哪个文件开始打包,并分析和构建内部依赖图。
2. Output
Output(输出)表示webpack打包的资源包输出到哪里,以及如何命名。
3. Loader
Webpack只能理解JavaScript和JSON文件,这是其自带的功能。让loader webpack处理其他类型的文件,并将其转换为有效的模块,这些模块可以被应用程序使用,并添加到依赖图中。
4. Plugins
插件可以用来执行更广泛的任务。插件的范围从包优化和压缩到重新定义环境中的变量。
5. Mode
模式表示webpack使用相应模式的配置。
下面详细介绍一下webpack的五大核心概念。
1、入口(Entry)
入口对象用于查找和启动webpack并构建包。入口是应用程序的起点。从这个起点开始,应用程序开始执行。如果你传递一个数组,那么数组中的每一项都会被执行。入口点指示webpack应该使用哪个模块作为构建其内部依赖图的起点。进入门户起点后,webpack会找出门户起点依赖于哪些模块和库(直接和间接)。
简单的规则:每个HTML页面都有一个入口起点。单页申请(SPA):一个入口起点,多页申请(MPA):多个入口起点。
默认值为。/src/index.js,但是您可以通过在webpack配置中配置entry属性来指定一个(或多个)不同的条目起点。例如:
//单个条目字符串
模块.导出={
条目:。/path/to/my/entry/file.js ,
};
//多条目数组
模块.导出={
条目:[。/src/index.js“,”。/src/add.js]
};
//多条目对象
模块.导出={
条目:{
首页:。/home.js ,
关于:。/about.js ,
联系人:。/contact.js
}
};条目的值类型:
String:单个条目,打包形成一个chunk,最后只会输出一个bundle文件。默认情况下,块的名称是main。
数组:多入口,所有的入口文件最后只会形成一个组块,最后输出一个bundle文件。默认情况下,块的名称是main。一般情况下,html热更新只有在HMR函数中使用才能生效。
对象:多条目,多少个键形成多少个块,输出多少个捆绑文件。每个键将是块的名称。在对象类型中,每个键的值也可以是数组,而不仅仅是字符串
2、输出(output)
output指示webpack如何以及在何处输出您的捆绑包、资产以及您已打包或加载的任何其他内容。输出包的默认值是。/dist/main.js和其他生成的文件放在。/dist文件夹。
您可以通过在配置中指定输出字段来配置这些流程:
//网页包.配置. js
const path=require( path );
模块.导出={
条目:。/path/to/my/entry/file.js ,
输出:{
path: path.resolve(__dirname, dist ),
文件名: my-first-webpack.bundle.js ,
},
};我们可以通过output.filename和output.path属性知道webpack包的名称以及包是在哪里生成的。
2.1、output.filename(文件名和目录)
这个选项决定了每个输出包的目录和名称。这些包将被写入由output.path选项指定的目录。
对于单个条目起点,filename将是一个静态名称。然而,当通过多入口点、代码分割或各种插件创建多个包时,应该使用其他方法来使每个包具有唯一的名称。
//在单个条目的情况下:
模块.导出={
//.
输出:{
文件名:“js/bundle.js”
}
};
//多门户-使用门户名称:
模块.导出={
//.
输出:{
文件名:“[名称].bundle.js”
}
};
//多条目-使用在每个构建过程中生成的唯一散列。
模块.导出={
//.
输出:{
文件名:[名称]。[hash].bundle.js
}
};
.2.2、output.path(文件目录)
Output.path指定所有输出文件的目录,即所有要输出的资源的公共目录。路径必须是绝对路径。
模块.导出={
//.
输出:{
path: path.resolve(__dirname, dist/assets )
}
};2.3、output.publicPath(引用资源的路径前缀)
PublicPath指定html文件中所有资源引入的公共路径前缀。它不影响生成文件的路径,但是当html文件引入各种资源时,publicPath会作为前缀添加到引入资源的路径中。
示例:
在vue-cli生成的webpack配置中,生产环境中publicPath的值默认为/,是当前目录的根目录。
打包后,我们打开html文件,可以看到html文件中引入的资源路径是:
如您所见,路径前面添加了/符号。当我们打开浏览器访问生成的html文件时,会发现一个错误,资源无法访问,并报告404。此时,资源访问类似于以下内容:
在服务器上,可能如下所示,但是访问也可能有问题。
我们可以将publicPath更改为相对路径,或者只是将其注释掉。
2.3.1、path和publicPath的区别
Path指定打包文件在硬盘中的存储位置,是webpack中所有文件的输出路径。必须是绝对路径。,如导出的js、图片、HtmlWebpackPlugin生成的html文件等。将存储在基于路径的目录中。PublicPath并不影响生成文件的路径,主要是完成引入你的页面的资源的路径。2.4、output.chunkFilename(非入口chunk的名称)
Output.chunkFilename确定非条目)块文件的名称。也就是说,除了导入文件生成的块之外,其他文件生成的块文件也被命名。
模块.导出={
//.
输出:{
chunk filename: js/[name]_ chunk . js //非条目块的名称。
}
};
3、loader
webpack本身只能封装JavaScript和JSON文件(webpack3和webpack2内置处理JSON文件,但webpack1不支持,需要引入json-loader),这是webpack自带的开箱即用的能力。Webpack本身不支持打包其他类型的文件,比如css、vue等。但是我们可以让webpack通过各种加载器处理这些类型的文件。Loader可以将不同语言的文件(如TypeScript)转换为JavaScript,或将内联图像转换为数据URL。loader甚至允许你直接在JavaScript模块中导入CSS文件!
通过使用不同的loader,webpack有能力调用外部脚本或工具来处理不同格式的文件,例如分析scss并将其转换为css,或者将下一代JS文件(ES6、ES7)转换为与现代浏览器兼容的JS文件。对于React的开发,合适的加载器可以将React中使用的JSX文件转换成JS文件。
在webpack的配置中,loader有两个属性:
测试属性以确定将转换哪些文件。
使用属性定义转换时应使用哪个加载程序。
包括/排除(可选):手动添加必须处理的文件(文件夹)或阻止不需要处理的文件(文件夹)。
查询(可选):为装入程序提供附加设置选项。
//示例:webpack.config.js
const path=require( path );
模块.导出={
输出:{
文件名: my-first-webpack.bundle.js ,
},
模块:{
规则:[
{测试:/\。txt$/,loader: raw-loader },
{测试:/\。css $/,use: [style-loader , CSS-loader ]}//如果使用了多个加载器,则应该使用use。
],
},
};在上面的配置中,rules属性是为单个模块对象定义的,它包含两个必需的属性:test和use。这相当于告诉webpack编译器使用raw-loader来转换被解析为的路径。请在打包之前在require()/import语句中添加“txt”。
如果你使用多个装载器,你应该在使用中使用装载器,使用数组执行顺序:从右到左依次执行。比如上面的css文件,首先css-loader会将css文件编译成JS并加载到JS文件中,然后style-loader会创建一个style标签并将JS中的样式资源插入head标签中。
3.1、CSS-loader
Webpack提供了两个处理样式表的工具,css-loader和style-loader,它们处理不同的任务。Css-loader使您能够以类似的方式导入Css文件。style-loader将所有计算出来的样式添加到页面中,两者的结合使你能够将样式表嵌入到webpack打包的JS文件中,从而将css文件引入JS文件中。
//安装
NP install-save-dev style-loader CSS-loader//CSS-loader的版本太高,编译时可能会出错。建议将css-loader@1.0.1等版本降低到可用//。
模块.导出={
.
模块:{
规则:[
{
测试:/(\。jsx\。js)$/,
使用:{
装载机:“巴别塔装载机”
},
排除:/node_modules/
},
{
测试:/\。css$/,//将多个加载器引入同一个文件的方法。装载机的动作顺序是后面的装载机先开始动作。
使用:[
{
加载器:“样式加载器”
}, {
加载程序:“css-loader”
}
]
}
]
}
};假设有一个main.css文件:
正文{
背景:绿色;
}为了让webpack找到“main.css”文件,我们将其导入到“main.js”中,如下所示:
//main.js
从“React”导入React;
从“react-dom”导入{ render };
从导入欢迎。/Greeter ;
“导入”。/main . CSS ;//使用require导入css文件
render(Greeter /,document . getelementbyid( root );通常情况下,css会和js打包到同一个文件中,并不会打包为一个单独的css文件。但是,通过正确配置webpack,css也可以打包为一个单独的文件。
4、插件(plugin)
loader用于转换某些类型的模块,而插件可用于执行更广泛的任务,包括:包优化、压缩、资源管理、环境变量注入等。插件的目的是解决loader无法实现的其他事情。
要使用插件,我们需要通过npm安装它,然后在plugins属性下添加插件的实例。因为插件可以携带参数/选项,所以必须将新实例传递给webpack配置中的plugins属性。大多数插件都可以通过选项进行定制,您也可以在一个配置文件中针对不同的目的多次使用同一个插件。
//网页包.配置. js
const HtmlWebpackPlugin=require( html-web pack-plugin );//通过npm安装
const web pack=require( web pack );//用于访问内置插件
模块.导出={
模块:{
规则:[{ test: /\。txt$/,使用: raw-loader }],
},
插件:[新的HtmlWebpackPlugin({ template:。/src/index.html })],
};在上面的例子中,HTML-webpack-plugin为应用程序生成一个HTML文件,并自动注入所有生成的bundle。
4.1、BannerPlugin插件(添加版权说明)
我们添加了一个插件,将版权声明添加到下面的打包代码中。这个插件是webpack内置的插件,不需要安装。
const web pack=require( web pack );
模块.导出={
.
模块:{
规则:[
{
测试:/(\。jsx\。js)$/,
使用:{
装载机:“巴别塔装载机”
},
排除:/node_modules/
},
{
测试:/\。css$/,
使用:[
{
加载器:“样式加载器”
}, {
加载程序: css-loader ,
选项:{
模块:真
}
}, {
加载程序:“postcss-loader”
}
]
}
]
},
插件:[
新包装。Banner Plugin(海,版权所有,违者必究)
],
};4.2、Hot Module Replacement 插件(热加载)
热模块替换(HMR)是webpack中一个非常有用的插件,可以让你在修改组件代码后,自动刷新并实时预览修改后的效果。热加载不同于webpack-dev-server。应用运行时,热替换可以在不刷新页面的情况下检查更新代码的效果,就像直接在浏览器上修改dom样式一样。但是,webpack-dev-server需要刷新页面。
(1)将HMR插件添加到webpack配置文件中;
(2)在Webpack Dev服务器中添加“hot”参数;
4.2.1、react实现热加载
React模块可以使用Babel实现功能热加载。Babel有个插件叫React-transform-hrm,不需要额外配置React模块就能让HMR正常工作;
安装react-transform-hmr
NPM install-save-dev babel-plugin-react-transform react-transform-hmr const web pack=require( web pack );
模块.导出={
Entry: _ _ dirname/app/main.js ,//唯一被多次提及的Entry文件。
输出:{
路径:__dirname /public ,
文件名:“bundle.js”
},
dev tool:“eval-source-map”,
devServer: {
基底:。/public ,//本地服务器加载的页面所在的目录
HistoryApiFallback: true,///不要跳转
inline: true,
热门:真的
},
模块:{
规则:[
{
测试:/(\。jsx\。js)$/,
使用:{
装载机:“巴别塔装载机”
},
排除:/node_modules/
},
{
测试:/\。css$/,
使用:[
{
加载器:“样式加载器”
}, {
加载程序: css-loader ,
选项:{
模块:真
}
}, {
加载程序:“postcss-loader”
}
]
}
]
},
插件:[
新包装。横幅插件(版权所有,盗版必究),
new pack . hotmodulereplacementplugin()//热加载插件
],
};配置巴别塔
//.巴伯尔克
{
预设:[反应,环境],
环境:{
发展:
插件:[[反应-转换,{
转换:[{
转换:反应-转换-hmr ,
imports: [react],
局部变量“:[模块]
}]
}]]
}
}
}//欢迎者,js
导入反应,{
成分
}来自“反应”
从导入样式。/main.css
类欢迎扩展组件{
render() {
返回(
差异
氕
一愣
/h1
/div
);
}
}
导出默认欢迎界面//main.js
从“React”导入React;
导入{
提出
}来自‘react-DOM’;
从导入欢迎。/greeter . js ;
render( Greeter /,document . getelementbyid( root );现在如果能实现热加载模块,每次保存的时候都可以直接在浏览器上看到更新的内容,浏览器也不用自己刷新或者自动刷新。
(有时没有效果可能是版本问题)
4.3、ExtractTextWebpackPlugin插件(抽离css)
默认情况下,webpack不会将css样式作为独立文件使用,但也会将css打包成js文件。打包生成的js文件会在渲染时通过js语法将样式以样式标签的形式插入页面。但是,在这种情况下,包文件可能太大了。此时,我们可以使用ExtractTextWebpackPlugin插件将css样式分离到css文件中。
ExtractTextWebpackPlugin插件将移动*。portal chunk中引用的css(包括引入的css文件和vue文件中style编写的样式)到一个独立的CSS文件中。ExtractTextPlugin会为每个条目组块生成一个对应的css文件,也就是说一个条目对应一个css文件,多个条目会分别生成多个对应的css文件。
使用ExtractTextWebpackPlugin插件,您的样式将不再嵌入JS bundle中,而是放在一个单独的CSS文件中(即styles.css)。如果你的样式文件很大,那么提前加载会更快,因为CSS bundle会和JS bundle并行加载。
const extract text plugin=require( extract-text-web pack-plugin );
模块.导出={
模块:{
规则:[
{
测试:/\。css$/,
使用:ExtractTextPlugin.extract({
回退:“样式加载器”,
使用:“css-loader”
})
}
]
},
插件:[
新的ExtractTextPlugin({
文件名:utils.assetspath (css/[name])。[内容哈希]。css ),//extracttextplugin为每个条目组块生成一个对应的文件,所以在配置多个条目组块时,必须使用[name],[id]或[contenthash]
//allChunks: true,//当使用CommonsChunkPlugin 并且公共块中有提取的块(来自ExtractTextPlugin.extract )时,必须将 allchunks * *设置为 true 。
}),
]
}4.3.1、allChunks选项(是否也将异步加载的样式一起提取出来)
ExtractTextWebpackPlugin插件的allChunks选项的默认值为false。
allChunks选项表示异步加载的样式是否需要一起提取。因为默认情况下,即使使用了ExtractTextWebpackPlugin插件,如果样式或样式文件是异步加载的,那么这些样式也不会被提取到单独的css文件中,仍然会打包到一个js文件中。
因此,allChunks:false是默认值。默认情况下,从entry的Entry中提取代码,但异步加载的代码不会被提取;AllChunks:true是将所有模块(包括异步加载的模块)的代码提取到一个文件中。如果使用了异步加载样式,但是allChunks设置为false,那么我们需要设置ExtractTextPlugin的fallback,extract fallback是在异步代码加载的css代码没有提取出来的情况下,用style-loader加载异步组件的样式。
5、模式(mode)
通过选择开发、生产或无之一来设置模式参数,您可以启用在相应环境中构建的webpack的优化。其默认值为生产。
模块.导出={
模式:“生产”,
};直接在配置文件中配置模式选项将告诉webpack使用相应模式的内置优化。模式选项包括开发、生产和无。
开发:开发模式,打包的代码不会被压缩,开始代码调试。
生产:生产方式,正好相反。
如果mode设置为development或production,webpack会自动设置process.env.NODE_ENV的值,可以直接在任何文件夹中获取。但是,如果只设置了NODE_ENV,则不会自动设置模式。(在node中,全局变量process代表当前节点流程。process.env属性包含有关用户环境的信息。process.env本身没有NODE_ENV属性。我们通常自己定义NODE_ENV属性,用它来判断是生产环境还是开发环境。)
(请注意:mode选项是webpack4中新增的,在4之前是用DefinePlugin插件设置的,在webpack4中已经删除了DefinePlugin)
5.1、vue-cli项目mode配置详解
在webpack中,NODE_ENV的值通常在配置文件中配置。在默认情况下使用vue-cli生成的vue项目中,NODE_ENV的配置如下:
//webpack.dev.conf.js文件,dev.env.js文件介绍。
新网络包。定义插件({
process.env: require(./config/dev.env )
}),//dev.env.js文件
module.exports=merge(prodEnv,{
NODE_ENV:“”开发“”
})//webpack.prod.conf.js文件,prod.env.js文件介绍。
const env=require(./config/prod.env )
新网络包。定义插件({
process.env: env
}),//prod.env.js文件
模块.导出={
NODE_ENV:“”生产“”
}从上面可以知道,在开发环境中,配置文件将NODE_ENV配置为‘development’;在生产环境中,配置文件将NODE_ENV配置为“生产”。
当我们运行项目时,我们将执行npm run dev或npm run build。这两个命令使用开发环境或者生产环境的配置文件来生成运行的项目,也对应了相应NODE_ENV值的配置,所以我们可以在项目的任意文件中获取相应的NODE_ENV值(配置文件不一定,因为这取决于用NODE_ENV值配置的配置文件是否有效)。
5.2、process.env.NODE_ENV配置
是processnode的全局变量,process具有属性env,但没有属性NODE_ENV。NODE_ENV变量在process.env中不是直接可用的,而是通过设置它来获得的。但是,NODE_ENV变量通常用于定义环境类型。这个变量的作用是:我们可以通过判断这个变量来区分开发环境和生产环境。
(1)可以通过webpack的内置插件 DefinePlugin 来设置全局变量值:
新网络包。定义插件({
process . ENV . node _ ENV :JSON . stringify( production )
}),设置好之后,就可以在执行脚本上得到这个值,比如:
//main.js
console . log(process . ENV . node _ ENV);//production但是这个值不能在webpack的配置文件webpack.config.js中取。
(2)通过 cross-env 包设置
首先下载跨环境包:
设置cnicross-env-d的package.json文件:
build : cross-ENV node _ ENV=test web pack-config web pack . config . js 此时可以在配置文件中获取值(process.env.NODE_ENV),但在可执行脚本中无法获取。它需要与DefinePlugin插件一起使用。
有关编程的更多信息,请访问:编程视频!以上是对webpack五大核心概念的深入分析细节。请多关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。