当前位置: 首页 > news >正文

租车网站建设方案/如何建网站教程

租车网站建设方案,如何建网站教程,wordpress event,上海百姓网1 基础回顾 首先我们先回顾一下webpack常见配置,因为后面会用到,所以简单介绍一下。 1.1 webpack常见配置 // 入口文件entry: {app: ./src/js/index.js,},// 输出文件output: {filename: [name].bundle.js,path: path.resolve(__dirname, dist),publi…

1 基础回顾

首先我们先回顾一下webpack常见配置,因为后面会用到,所以简单介绍一下。

1.1 webpack常见配置

// 入口文件entry: {app: './src/js/index.js',},// 输出文件output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/'     //确保文件资源能够在 http://localhost:3000 下正确访问},// 开发者工具 source-mapdevtool: 'inline-source-map',// 创建开发者服务器devServer: {contentBase: './dist',hot: true                // 热更新},plugins: [// 删除dist目录new CleanWebpackPlugin(['dist']),// 重新穿件html文件new HtmlWebpackPlugin({title: 'Output Management'}),// 以便更容易查看要修补(patch)的依赖new webpack.NamedModulesPlugin(),// 热更新模块new webpack.HotModuleReplacementPlugin()],// 环境mode: "development",// loader配置module: {rules: [{test: /\.css$/,use: ['style-loader','css-loader']},{test: /\.(png|svg|jpg|gif)$/,use: ['file-loader']}]}
复制代码

这里面我们重点关注 module和plugins属性,因为今天的重点是编写loader和plugin,需要配置这两个属性。

1.2 打包原理

  • 识别入口文件
  • 通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖)
  • webpack做的就是分析代码。转换代码,编译代码,输出代码
  • 最终形成打包后的代码

这些都是webpack的一些基础知识,对于理解webpack的工作机制很有帮助。

2 loader

OK今天第一个主角登场

2.1 什么是loader?

loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中

  • 处理一个文件可以使用多个loader,loader的执行顺序是和本身的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行。
  • 第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数。最后执行的loader会返回此模块的JavaScript源码

2.2 手写一个loader

需求:

  1. 处理.txt文件
  2. 对字符串做反转操作
  3. 首字母大写

例如:abcdefg转换后为Gfedcba

OK,我们开始

1)首先创建两个loader(这里以本地loader为例)

为什么要创建两个laoder?理由后面会介绍

 

image

 

 

reverse-loader.js

module.exports = function (src) {if (src) {console.log('--- reverse-loader input:', src)src = src.split('').reverse().join('')console.log('--- reverse-loader output:', src)}return src;
}
复制代码

uppercase-loader.js

module.exports = function (src) {if (src) {console.log('--- uppercase-loader input:', src)src = src.charAt(0).toUpperCase() + src.slice(1)console.log('--- uppercase-loader output:', src)}// 这里为什么要这么写?因为直接返回转换后的字符串会报语法错误,// 这么写import后转换成可以使用的字符串return `module.exports = '${src}'`
}
复制代码

看,loader结构是不是很简单,接收一个参数,并且return一个内容就ok了。

然后创建一个txt文件

 

image

 

 

2)mytest.txt

abcdefg
复制代码

3)现在开始配置webpack

module.exports = {entry: {index: './src/js/index.js'},plugins: [...],optimization: {...},output: {...},module: {rules: [...,{test: /\.txt$/,use: ['./loader/uppercase-loader.js','./loader/reverse-loader.js']}]}
}
复制代码

这样就配置完成了

4)我们在入口文件中导入这个脚本

为什么这里需要导入呢,我们不是配置了webapck处理所有的.txt文件么?

因为webpack会做过滤,如果不引用该文件的话,webpack是不会对该文件进行打包处理的,那么你的loader也不会执行

import _ from 'lodash';
import txt from '../txt/mytest.txt'
import '../css/style.css'
function component() {var element = document.createElement('div');var button = document.createElement('button');var br = document.createElement('br');button.innerHTML = 'Click me and look at the console!';element.innerHTML = _.join('【' + txt + '】');element.className = 'hello'element.appendChild(br);element.appendChild(button);// Note that because a network request is involved, some indication// of loading would need to be shown in a production-level site/app.button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {var print = module.default;print();});return element;
}
document.body.appendChild(component());
复制代码

package.json配置

{...,"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack --config webpack.prod.js","start": "webpack-dev-server --open --config webpack.dev.js","server": "node server.js"},...
}复制代码

然后执行命令

npm run build
复制代码

 

image

 

 

这样我们的loader就写完了。

现在回答为什么要写两个loader?

看到执行的顺序没,我们的配置的是这样的

use: ['./loader/uppercase-loader.js','./loader/reverse-loader.js'
]
复制代码

正如前文所说,处理一个文件可以使用多个loader,loader的执行顺序是和本身的顺序是相反的

我们也可以自己写loader解析自定义模板,像vue-loader是非常复杂的,它内部会写大量的对.vue文件的解析,然后会生成对应的html、js和css。

我们这里只是讲述了一个最基础的用法,如果有更多的需要,可以查看 《loader官方文档》

3 plugin

3.1 什么是plugin?

在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

plugin和loader的区别是什么?

对于loader,它就是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss或A.less转变为B.css,单纯的文件转换过程

plugin是一个扩展器,它丰富了wepack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务。

3.2 一个最简的插件

/plugins/MyPlugin.js(本地插件)

class MyPlugin {// 构造方法constructor (options) {console.log('MyPlugin constructor:', options)}// 应用函数apply (compiler) {// 绑定钩子事件compiler.plugin('compilation', compilation => {console.log('MyPlugin')))}
}module.exports = MyPlugin
复制代码

webpack配置

const MyPlugin = require('./plugins/MyPlugin')
module.exports = {entry: {index: './src/js/index.js'},plugins: [...,new MyPlugin({param: 'xxx'})],...
};
复制代码

这就是一个最简单的插件(虽然我们什么都没干)

  • webpack 启动后,在读取配置的过程中会先执行 new MyPlugin(options) 初始化一个 MyPlugin 获得其实例。
  • 在初始化 compiler 对象后,再调用 myPlugin.apply(compiler) 给插件实例传入 compiler 对象。
  • 插件实例在获取到 compiler 对象后,就可以通过 compiler.plugin(事件名称, 回调函数) 监听到 Webpack 广播出来的事件。
  • 并且可以通过 compiler 对象去操作 webpack。

看到这里可能会问compiler是啥,compilation又是啥?

  • Compiler 对象包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;

  • Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。

Compiler 和 Compilation 的区别在于:

Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译。

3.3 事件流

  • webpack 通过 Tapable 来组织这条复杂的生产线。
  • webpack 的事件流机制保证了插件的有序性,使得整个系统扩展性很好。
  • webpack 的事件流机制应用了观察者模式,和 Node.js 中的 EventEmitter 非常相似。

绑定事件

compiler.plugin('event-name', params => {...	  
});
复制代码

触发事件

compiler.apply('event-name',params)
复制代码

3.4 需要注意的点

  • 只要能拿到 Compiler 或 Compilation 对象,就能广播出新的事件,所以在新开发的插件中也能广播出事件,给其它插件监听使用。
  • 传给每个插件的 Compiler 和 Compilation 对象都是同一个引用。也就是说在一个插件中修改了 Compiler 或 Compilation 对象上的属性,会影响到后面的插件。
  • 有些事件是异步的,这些异步的事件会附带两个参数,第二个参数为回调函数,在插件处理完任务时需要调用回调函数通知 webpack,才会进入下一处理流程。例如:
compiler.plugin('emit',function(compilation, callback) {...// 处理完毕后执行 callback 以通知 Webpack // 如果不执行 callback,运行流程将会一直卡在这不往下执行 callback();
});
复制代码

关于complier和compilation,webpack定义了大量的钩子事件。开发者可以根据自己的需要在任何地方进行自定义处理。

《compiler钩子文档》

《compilation钩子文档》

3.5 手写一个plugin

场景:

小程序mpvue项目,通过webpack编译,生成子包(我们作为分包引入到主程序中),然后考入主包当中。生成子包后,里面的公共静态资源wxss引用地址需要加入分包的前缀:/subPages/enjoy_given。

在未编写插件前,生成的资源是这样的,这个路径如果作为分包引入主包,是没法正常访问资源的。

 

image

 

 

所以需求来了:

修改dist/static/css/pages目录下,所有页面的样式文件(wxss文件)引入公共资源的路径。

因为所有页面的样式都会引用通用样式vender.wxss

那么就需要把@import "/static/css/vendor.wxss"; 改为:@import "/subPages/enjoy_given/static/css/vendor.wxss";
复制代码

OK 开始!

1)创建插件文件 CssPathTransfor.js

 

image

 

 

CssPathTransfor.js

class CssPathTransfor {apply (compiler) {compiler.plugin('emit', (compilation, callback) => {console.log('--CssPathTransfor emit')// 遍历所有资源文件for (var filePathName in compilation.assets) {// 查看对应的文件是否符合指定目录下的文件if (/static\/css\/pages/i.test(filePathName)) {// 引入路径正则const reg = /\/static\/css\/vendor\.wxss/i// 需要替换的最终字符串const finalStr = '/subPages/enjoy_given/static/css/vendor.wxss'// 获取文件内容let content = compilation.assets[filePathName].source() || ''content = content.replace(reg, finalStr)// 重写指定输出模块内容compilation.assets[filePathName] = {source () {return content;},size () {return content.length;}}}}callback()})}
}
module.exports = CssPathTransfor
复制代码

看着挺多,实际就是遍历compilation.assets模块。对符合要求的文件进行正则替换。

2)修改webpack配置

var baseWebpackConfig = require('./webpack.base.conf')
var CssPathTransfor = require('../plugins/CssPathTransfor.js')var webpackConfig = merge(baseWebpackConfig, {module: {...},devtool: config.build.productionSourceMap ? '#source-map' : false,output: {...},plugins: [...,// 配置插件new CssPathTransfor(),]
})
复制代码

插件编写完成后,执行编译命令

 

image

 

 

搞定~

如果有更多的需求可以参考《如何写一个插件》


作者:转转_陈龙
链接:https://juejin.im/post/5bbf190de51d450ea52fffd3
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

http://www.lbrq.cn/news/820387.html

相关文章:

  • 国家建设部人才交流中心网站/百度网盘pc端网页版
  • 网站开发与网页设计/自助发外链网站
  • 知末网su模型免费下载/网站关键词优化推广哪家快
  • 学仿网站/创意营销点子
  • 南京做网站设计/娄底地seo
  • 北仑网站建设培训/广州公关公司
  • proxy网站/北京互联网公司有哪些
  • 百度云盘资源搜索/seo网站优化公司
  • 网站建设的法律问题/广州seo技术优化网站seo
  • 网站建设seo网络推广/sem搜索引擎营销
  • 家庭宽带做网站服务器/百度博客收录提交入口
  • 做游戏网站需要多少钱/网站建设报价单
  • 企业网站开发教程/济南做网站公司
  • 集团公司网站怎么做/抖音seo怎么做
  • 网站制作的前期主要是做好什么工作/互联网seo是什么
  • 淄博网站建设咨询臻动传媒/国外免费ip地址
  • 黄金网站app视频/2023年免费进入b站
  • 找在家做的兼职上什么网站好/手机关键词seo排名优化
  • 网站维护中怎么解决/网站建设外包
  • 杭州网站设计 site/百度指数的主要用户是
  • 学校网站搭建/推广软文模板
  • wordpress快速建站教程视频教程/soso搜索引擎
  • 建设人力资源服务网站工作方案/百度指数数据官网
  • 北京建设注册中心网站首页/seo整站优化服务
  • 如何更改 网站 关键词/网站标题优化排名
  • 网站建设知乎/百度官网入口
  • 荆州网站建设 众火网/b2b国际贸易平台
  • wordpress文章全部随机排/百度seo优化包含哪几项
  • 邯郸哪有做网站的公司/外链seo
  • 昆明双鼎网站制作/重庆森林粤语
  • 工具篇之开发IDEA插件的实战分享
  • Unity 多人游戏框架学习系列九
  • Apache 消息队列分布式架构与原理
  • 达梦数据库表字段增加时报错[-2106]:无效的表或视图名,[-2116]:列[IS_REPEAT]已存在
  • 赋能未来数学课堂——基于Qwen3、LangChain与Agent架构的个性化教辅系统研究
  • ISPDiffuser文章翻译理解