首页 > 其他分享 >webpack与其常见loader加载器使用方式

webpack与其常见loader加载器使用方式

时间:2022-12-04 14:22:43浏览次数:48  
标签:index modules js webpack loader 加载

webpack是什么 webpack是前端项目工程化的具体解决方案。 主要功能:提供了友好的前端模块化开发支持,已经代码压缩混淆(去除空格和注释,让文件体积更小),处理浏览器端JS的兼容性(将箭头函数转成低级实现,let->var实现,兼容版本低的浏览器),性能优化等。 让程序员把重心放到具体的功能实现上,提高了前端开发效率和项目的可维护性。 Vue和React都是使用webpack做工程化开发的。   创建一个测试项目 使用npm init -y快速创建一个项目 然后创建index.js, index.html文件 然后npm i jquery -S 安装jQuery包 执行npm run dev 进行打包

zhoufeideMacBook-Pro-2:webpack-demo zhoufei$ npm run dev

> [email protected] dev
> webpack

asset main.js 325 KiB [emitted] (name: main)
runtime modules 937 bytes 4 modules
cacheable modules 283 KiB
  ./src/index.js 136 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 283 KiB [built] [code generated]
webpack 5.42.1 compiled successfully in 281 ms

底层实际运行的是 webpack工具, webpack对整个项目进行处理,瘦身,混淆,向下兼容,性能优化。最终生成了资源asset main.js, 产物放置在dist文件夹下面

asset main.js内部总共有两部分组成
cacheable modules 283 KiB
./src/index.js 136 bytes [built] [code generated]
./node_modules/jquery/dist/jquery.js 283 KiB [built] [code generated]

里面即包含了自定义的index.js代码,也包含了引用的第三方库jquery的代码。

项目中webpack.config.js配置文件的读取时机是执行命令npm run dev时,读取webpack.config.js配置文件,拿到配置后然后再运行webpack工具。  webpack默认约定 默认的打包入口是:src -> index.js 默认的输出文件路径:dist -> main.js 可以通过在webpack.config.js中新增自定义打包入口定义和打包导出说明来自定义webpack的打包入口和出口
    entry: path.join(__dirname, "./src/index123.js"), //自定义webpack的打包入口
    output: {
        path: path.join(__dirname, "./dist"), //自定义webpack的打包导出目录
        filename: 'bundle.js' //自定义webpack的打包导出文件名
    }
npm i [email protected] -D

对webpack.config.js配置文件修改dev脚本,增加server子命令

   "scripts": {
+    "dev": "webpack serve"
   },

安装webpack-dev-server服务,会在本地开通一个http服务器,用来监听源代码的改动,一旦修改就会自动执行webpack编译,生成编译产物,只需要刷新页面就可以看到修改的效果。

运行webpack脚本
zhoufeideMacBook-Pro-2:webpack-demo zhoufei$ npm run dev

> [email protected] dev
> webpack serve

[webpack-cli] Unable to load '@webpack-cli/serve' command
[webpack-cli] TypeError: options.forEach is not a function

报错,应该是webpack-cli之前的版本比较低,通过安装最新版本的webpack-cli解决

npm install webpack-cli -D

 

webpack-dev-server的工作原理 当运行脚本npm run dev执行webpack serve服务时
zhoufeideMacBook-Pro-2:webpack-demo zhoufei$ npm run dev

> [email protected] dev
> webpack serve

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Users/zhoufei/Documents/Vue/webpack-demo
ℹ 「wdm」: asset bundle.js 650 KiB [emitted] (name: main)
runtime modules 1.25 KiB 6 modules
cacheable modules 581 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 20.9 KiB 10 modules
  modules by path ./node_modules/html-entities/lib/*.js 61 KiB 5 modules
  modules by path ./node_modules/url/ 37.4 KiB 3 modules
  modules by path ./node_modules/querystring/*.js 4.51 KiB
    ./node_modules/querystring/index.js 127 bytes [built] [code generated]
    ./node_modules/querystring/decode.js 2.34 KiB [built] [code generated]
    ./node_modules/querystring/encode.js 2.04 KiB [built] [code generated]
  modules by path ./node_modules/webpack/hot/ 1.42 KiB
    ./node_modules/webpack/hot/emitter.js 75 bytes [built] [code generated]
    ./node_modules/webpack/hot/log.js 1.34 KiB [built] [code generated]
./node_modules/webpack/hot/ sync nonrecursive ^\.\/log$ 170 bytes [built] [code generated]
webpack 5.42.1 compiled successfully in 463 ms
ℹ 「wdm」: Compiled successfully.

首先,在项目的根目录创建一个http服务器,让http服务器管理当前项目。

「wds」: Project is running at http://localhost:8080/

然后,webpack打包,将产物放到了服务器根节点/, 也就是项目的根目录 的内存中,而非硬盘上,所以在本地目录是看不到产物的产生。放在内存中的目的是访问速度快,因为在编辑过程中是频繁保存的。

然后, 修改html页面上javascript的引用路径
<script src="/bundle.js"></script>

然后, 打开服务器地址中的src目录,注意浏览器在打开一个目录时,默认展示这个目录下面的index.html页面。

http://localhost:8080/src/

解决http://localhost:8080访问时展示的是项目目录而非index.html首页的问题

安装html-webpack-plugin自动拷贝插件,在webpack运行时,会自动从./src/index.html拷贝一份到项目根目录的内存中,注意这个根目录的index.html也是保存在内存中,在项目目录结构中是看不到的。
npm i [email protected] -D

webpack.config.js文件修改

//导入插件,得出一个构造函数
const HtmlPlugin = require('html-webpack-plugin')
//创建插件实例对象
const htmlplugin = new HtmlPlugin({
    template: './src/index.html', //copy文件路径源
    filename: './index.html'      //copy文件路径目标
})

module.exports = {
    plugins: [
        htmlplugin //添加htmlplugin插件对象,webpack在运行前,读取这个插件实例并运行
    ]

}

执行npm run dev重启后,在地址http://localhost:8080/就可以看到index.html首页了。

html-webpack-plugin的作用有2个: 1.自动将./src/index.html页面复制一份到项目根目录,放到了内存中。 2.在内存中自动生成的index.html页面里,自动注入webpack打包的存在于内存中的bundle.js文件
<script defer="" src="bundle.js"></script>

这些配置webpack, html-webpack-plugin如果使用Vue-Cli工具是可以自动配置的。

webpack-dev-server包的开发服务器设置
 devServer: {
        open: true, //首次打包成功后,默认打开浏览器, 
        port: 8888, //设置使用的端口,http如果使用的80端口,默认是可以忽略的
        host: '127.0.0.1', //指定运行的主机地址
    }
  webpack打包流程 webpack中的loader webpack默认只能打包处理以.js结尾的模块。其他非.js后缀名结尾的模块,webpack默认是不处理的。需要调用loader加载器才可以正常打包,否则会报错。  loader加载器的作用:协作webpack打包处理约定的文件模块。比如: css-loader: 可以打包处理.css相关的文件 less-loader: 可以打包处理.less相关的文件 babel-loader: 可以打包处理webpack无法处理的高级js语法 webpack打包流程图

 

在webpack入口index.js中导入css
import $ from 'jquery'

//webpack的打包入口是这里,所以将index.css从这里引入就可以被打包进去
//ES6中,一切皆模块,所以使用import导入
import './css/index.css'


$(function () {
    $('li:odd').css('background-color','red')
    $('li:even').css('background-color','green')
})

执行npm run dev打包报错,提示没有安装css加载器

ℹ 「wdm」: Compiling...
✖ 「wdm」: asset bundle.js 651 KiB [emitted] (name: main)
asset ./index.html 688 bytes [emitted]
cached modules 294 KiB [cached] 32 modules
runtime modules 1.25 KiB 6 modules
./src/css/index.css 30 bytes [built] [code generated] [1 error]

ERROR in ./src/css/index.css 1:3
Module parse failed: Unexpected token (1:3)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> li {
|     list-style: none;
| }
 @ ./src/index123.js 5:0-24

webpack 5.42.1 compiled with 1 error in 47 ms
ℹ 「wdm」: Failed to compile.

 

安装css模块加载器loader

 安装加载器包
npm i [email protected] [email protected] -D

在webpack.config.js配置文件中,把加载器匹配规则在里面设置好

module.exports = {
    module: { //非js模块: webpack默认处理的模块是js结尾的。如果碰到其他模块,就查询这个key, 查询它们有没有对应的加载器,然后把这个模块交给对应的加载器
        rules: [
            //test: 要匹配的文件类型, 
            //use:  要调用的loader,其中use数组的顺序是固定的,调用顺序是从后往前
            {test: /\.css$/, use:['style-loader', 'css-loader']}
        ]
    }

}

webpack打包工具以webpack.config.js中entry声明的入口文件index.js为入口,去处理模块。

由于webpack默认只处理js结尾的文件,当遇到其他css结尾的文件时,就会查询webpack.config.js配置文件,查看module字段,查询是否有配置对应css结尾的模块的加载器。 如果找到了对应配置的加载器,就会根据rules数组从后到前,把css模块文件或其中间处理的结果传递,一次处理。然后把最后的处理结果交给webpack。 最后webpack将它默认处理的js模块+其他加载器处理的结果合并到一起,写入到/dist/bundle.js结果文件中。   less, less-loader加载器的安装 less是less-loader的内部依赖,所以添加less-loader加载器也要添加less库
npm i [email protected] [email protected] -D
创建index.less文件,并在入口文件index.js中导入
//文件:index.less

html, body, ul {
    margin: 0;
    padding: 0;
    li {
        margin: 0;
        padding: 0;
        line-height: 30px;
        padding-left: 20px;
        font-size: 12px;
    }
}
//文件:index.js

//导入less类型模块
import './css/index.less'

在webpack.config.js配置文件中添加less-loader加载器模块的匹配规则,让webpack打包时使用less-loader进行处理less结尾的文件

//文件:webpack.config.js

module.exports = {

    module: { //非js模块: webpack默认处理的模块是js结尾的。如果碰到其他模块,就查询这个key, 查询它们有没有对应的加载器,然后把这个模块交给对应的加载器
        rules: [
            //use数组中的处理顺序是从后向前,逐个处理并将处理结果传递到后面进行处理
            //less库 是less-loader库加载器的内部依赖项,所以需要安装单不需要添加到处理规则中
            {test: /\.less$/, use:['style-loader', 'css-loader', 'less-loader']},
        ]
    }

}

然后npm run dev重启生效

  添加url-loader, file-loader加载器将小图转成base64优化性能 安装图片加载器
npm i [email protected] [email protected] -D

在webpack.config.js配置的入口文件中使用jquery加载图片模块并动态设置到img标签上

//文件:index.js

//导入图片类型模块
import img from './images/cat.jpeg'

$('.box').attr('src',img)

在webpack.config.js中添加url-loader加载器规则匹配,并设置limit最大字节数控制,当小于这个限制时,webpack会自动转成base64优化图片加载

module.exports = {
    module: { //非js模块: webpack默认处理的模块是js结尾的。如果碰到其他模块,就查询这个key, 查询它们有没有对应的加载器,然后把这个模块交给对应的加载器
        rules: [
           
            //file-loader库 是url-loader加载器的内部依赖项,所以需要安装
            //如果匹配的use加载器只有一个时,可以直接写成字符串,或者写成数组也可以
            //limit参数为最大值设置,单位是字节,当大于这个限制时,图片使用网络请求获取,当小于这个3500字节时,图片会被转成base64随网页标签一起返回
            {test: /\.png|jpg|jpeg|gif$/, use:'url-loader?limit=3500'},
        ]
    }

}

然后npm run dev重启项目,生效。

在入口文件index.js中导入的模块,最后都会被打包到bundle.js文件中 import './css/index.css' 只导入,不接收 import img from './images/cat.jpeg' 导入,并用img对象接收
import $ from 'jquery'

//webpack的打包入口是这里,所以将index.css从这里引入就可以被打包进去
//ES6中,一切皆模块,所以使用import导入
import './css/index.css'
//导入less类型模块
import './css/index.less'
//导入图片类型模块
import img from './images/cat.jpeg'

$('.box').attr('src',img)

$(function () {
    $('li:odd').css('background-color','red')
    $('li:even').css('background-color','green')
})

 

加载babel-loader处理webpack无法处理的高级语法 安装babel-loader及其依赖包
npm i [email protected] @[email protected] @babel/[email protected] -D

在webpack.config.js配置的入口文件中添加js高级语法@info装饰器语法

function info(target) {
    //为对象添加静态属性
    target.info = 'Person info'
}

//使用一个webpack默认不支持的高级语法,装饰器,此时webpack会查询是否有其他rules中结尾为js的laoder加载器可以处理这个高级语法
@info
class Person {}


console.log(Person.info);

在webpack.config.js配置文件中添加babel-loader加载器,用来处理js中webpack无法处理的高级js语法。同时设置exclude,排除/node_modules/目录下的第三方包,只处理自己项目中的js文件

module.exports = {
    module: { //非js模块: webpack默认处理的模块是js结尾的。如果碰到其他模块,就查询这个key, 查询它们有没有对应的加载器,然后把这个模块交给对应的加载器
        rules: [
            //js结尾文件中,webpack默认不能处理的高级语法走下面匹配的loader加载器
            //exclude排除/node_modules/目录下的第三方包
            {test: /\.js$/, use:'babel-loader', exclude: /node_modules/},
        ]
    }

}

创建并配置babel.config.js, babel的配置文件,用于说明有哪些插件可以供babel-loader加载器使用。

//插件的插件
//babel-loader插件在加载时,会读取babel.config.js配置文件,查询是否有它需要的插件要加载
//这里通过plugin-proposal-decorators来处理js的高级语法“装饰器”语法
module.exports = {
    plugins: [
        ['@babel/plugin-proposal-decorators', {legacy: true}]
    ]
}

然后npm run dev重启服务。

  发布 在package.json中新增脚本build。 对应webpack打包命令时,要指定mode为生产模式,如果在命令中加了--mode, 那么这个命令参数会覆盖webpack.config.js中的mode模式设置。 然后最后生成的dist目录就是要发布的内容。里面webpack做了压缩,混淆。
 "scripts": {
    "build": "webpack --mode production"
  },

产物导出优化

把bundle.js产物导出到js目录下,把图片产物导出到images目录下 修改webpack.config.js的配置,对应增加参数“js/bundle.js”, “url-loader?limit=3500&outputPath=images”
module.exports = {
    output: {
        path: path.join(__dirname, "./dist"), //自定义webpack的打包导出目录
        filename: 'js/bundle.js' //自定义webpack的打包导出文件名
    },
      module: { //非js模块: webpack默认处理的模块是js结尾的。如果碰到其他模块,就查询这个key, 查询它们有没有对应的加载器,然后把这个模块交给对应的加载器
        rules: [
            //file-loader库 是url-loader加载器的内部依赖项,所以需要安装
            //如果匹配的use加载器只有一个时,可以直接写成字符串,或者写成数组也可以
            //limit参数为最大值设置,单位是字节,当大于这个限制时,图片使用网络请求获取,当小于这个3500字节时,图片会被转成base64随网页标签一起返回
            {test: /\.png|jpg|jpeg|gif$/, use:'url-loader?limit=3500&outputPath=images'},
         ]
    }

}

添加clean-webpack-plugin插件,使打包前自动删除dist目录

npm i clean-webpack-plugin -D

修改webpack.config.js配置文件,将插件实例配置到插件plugins项下

const {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = {
    plugins: [
        new CleanWebpackPlugin(),
    ],

}

解决浏览器中js报错展示的行不对应源码真实行号的问题

修改webpack.config.js文件,添加devtool配置字段。 注意:devtool在production生产环境和dev开发环境配置是不一样的。
module.exports = {
    //开发阶段
    //在开发阶段打开这个设置,可以在浏览器的js报错定位到源码的对应行数,点击能直接跳到源码。
    //如果不设置的话:浏览器的js报错定位是webpack打包对应的内存包的行数,点击查看跳的是内存结果bundle.js包
    devtool: 'eval-source-map', //开发阶段,即展示源码行号,又可以跳到源码

    // //生产阶段,建议使用nosources-source-map或者关闭该配置
    // devtool: 'nosources-source-map', //生产阶段,可以展示源码行号,但不能跳到源码
    // devtool: 'source-map', //生产阶段,即展示源码行号,又可以跳到源码,不建议这样配置
    
    mode: "development", //mode: development, production 开发模式与生产模式配置
}

使用@符号导入模块

修改webpack.config.js文件,添加符号“@”软连接,用于方便模块导入 如:使用“@/images/logo.jpj”来导入模块
module.exports = {
    resolve: {
        //告诉webpack,@符号表示src这一层目录, 开始时推荐使用“@/images/logo.jpj”来导入模块
        alias: {
            "@": path.join(__dirname, './src/')
        }
    }

}

 

demo地址:https://github.com/zhfei/webpack-demo 

标签:index,modules,js,webpack,loader,加载
From: https://www.cnblogs.com/zhou--fei/p/16949800.html

相关文章

  • Vue-treeselect 实现下拉树懒加载,末节点不要箭头
    项目需要,可选择的下拉树,由于数据过多,显示要有层级感,所以使用了懒加载模式vue-treeselect官网:https://www.vue-treeselect.cn/1、前端代码1、下载依赖npminstall--sav......
  • 类加载过程总结
    类的加载机制过程加载(loading)通过一个类的全限定名来获取定义此类的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代......
  • webpack
    目录简介解密方式简介!function(allModule){functionuseModule(whichModule){allModule[whichModule].call(null,"helloworld!");}useMod......
  • springbootMVC02(Bean加载控制)
    大纲:本节的问题就是解决"spring和springMVC要加载对应的Bean,要怎么操作"一、思考和处理思路二、对上面图片的总结:三、对解决方法的"代码块"3.1在config包下建"spr......
  • 协程及其实现,图片懒加载
    一、什么是协程?答:协程就是一个无优先级的子程序调度组件,允许子程序在特定的地方挂起和恢复。协程包含于线程,线程包含于进程。只要内存足够,一个线程可以有任意多个协程,但某......
  • 【Django学习】加载site-packages下的template
      TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates',#'DIRS':['frontend/dist'],'DIRS':[os.path.join......
  • iOS上架之App Uploader辅助工具激活码获取
    1. 点击图示的激活,获取激活码。2. 如图示,点击链接:​​http://www.applicationloader.net/purchase.html​​。会跳转购买激活码页面,购买成功即可生成激活码,购买的激活码越......
  • App Uploader下载安装
    ​1. 进入AppUploader官网下载。下载地址:​​http://www.applicationloader.net/​​2. 最新版本下载地址​​https://net-appuploader.oss-cn-qingdao.aliyuncs.com/app......
  • App Uploader下载安装
     进入AppUploader官网下载。下载地址:http://www.applicationloader.net/最新版本下载地址https://net-appuploader.oss-cn-qingdao.aliyuncs.com/appuploade......
  • Listview中使用线程实现无限加载更多项目的功能
    在现在的SINA微博或者象twitter,dzone等网站中,当加载一个很长的列表时,往往都是先加载部分内容,然后当用户用拖拉条往下拖动时,再加载更多的内容.这......