在webpack中使用预处理器(loader)简化开发

今天升级一个Vue项目,需要简化新增组件时的开发流程,具体地说,是需要把某个目录设定为组件文件夹,项目打包的时候自动把此文件夹中的组件文件引入到项目的一个多用途组件并注册到components中。

总体思路是先在要写入引用代码和注册代码的地方用注释写两个插槽标记,再写个脚本把文件夹里的组件读出来,生成引用代码和注册代码,最后简单地把插槽标记替换成生成好的代码。

插槽如下:

<script>

  /** slot-import */

  export default {

    components: {

      /** slot-components */

    }

  }

</script>

读取组件如下:

const fs= require('fs')

const path= require('path')

const componentDir= path.resolve(process.cwd(), './src/components') // 组件文件夹

const componentList = fs.readdirSync(componentDir, {

  encoding: 'utf8', withFileTypes: true

})

const componentSet = []

for (let i= 0; i< componentList.length; i++) {

  const n= path.resolve(componentDir, componentList[i].name)

  componentSet.push([ri.name.match(/^(\S+)\./)[1], n])

}

生成引用和注册代码如下:

let importState= ``

let compoentsState= ``

for (let i= 0; i< componentSet.length; i++) {

  const [name, path] = componentSet[i]

  importState+= `\nimport `

  importState+= name

  importState+= ` from `

  importState+= `'${path}'`

  compoentsState+= `\n      ${name},`

}

用代码替换插槽如下:

const theFile = path.resolve(process.cwd(), './src/pages/multiFunc.vue') // 多功能组件文件夹

fs.readFile(theFile, 'utf8', (err, data) => {

  if (err) {

    console.log('err', err)

}

  let code= data

  code= code.replace('/** slot-import */', importState)

  code= code.replace('/** slot-components */', compoentsState)

  console.log(code)

  fs.writeFileSync(theFile, code)

})

一开始我想着把脚本放根目录,改一下package.json里的scripts,让webpack在打包前自动运行一下脚本完事。但是写完脚本运行完发现行不通,脚本运行一次之后插槽标记就已经变成生成好的代码了,执行第二次就没用了,哪怕添加逻辑让脚本进行替换,也要面临难以预知的bug,而且很容易发现这个方法可能并不是最佳实践。

我马上想到了webpackloader,很多项目都依靠loader在项目打包前预处理项目文件中的svg、sass之类的。

所以我把上面改成了预处理器代码,命名为script.js,主体其实没有多大区别,只是把用代码替换插槽部分改成一个函数,接收代码作为参数,返回处理后的代码(代码其他部分可以放到函数外):

module.exports= function(sourceCode) {

  let code= sourceCode

  code= code.replace('/** slot-import */', importState)

  code= code.replace('/** slot-components */', compoentsState)

  return code

}

到此为止,脚本部分就完成了。

接下来把它发布到npm上,以便在使用,我使用的命令行(macOS环境)如下:

创建并文件夹

mkdir myloader

cd myloader

初始化,按提示输入配置(后续可以在package.json中查看、修改)

npm init

把写好的脚本文件复制到文件夹内,命名为index.js(和你上面配置的入口文件名一致)

cp ../script.js index.js

发布模块

npm publish

如果没登录,可以登录后操作

npm login

如果出现类似409 Conflict - PUT https://mirrors.cloud.tencent.com/npm/-/user/org.couchdb.user:xxxxxx - user registration disabled,可以用以下命令查看npm的配置项,有可能需要恢复默认值

npm config list

恢复配置项默认值命令为

npm config delete xxxxxx

不出意外,模块就成功发布到npm.js上了,我们可以在项目里进行安装

npm i -D myloader

接下来我们在vue.config.js中添加预处理器配置(链式配置):

chainWebpack(config) {

  config.module

  .rule('myLoader')

    .include

      .add(resolve('src/pages/multiFunc.vue'))

    .end()

    .use('myLoader')

    .loader('myLoader')

    .end()

}

项目升级完毕。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容