Part 8: 使用模塊的Alias別名來(lái)增強(qiáng)Jest的可配置度(完結(jié))

Enhance Jest configuration with Module Aliases

使用模塊的Alias別名來(lái)增強(qiáng)Jest的可配置度

Learn how to use Module Aliases Jest configuration to avoid using relative paths.
學(xué)習(xí)如何用模塊別名來(lái)配置Jest,這樣可以避免使用相對(duì)地址。

The module managers we have in the JavaScript community, mainly ES Modules and CommonJS, don’t support project-based paths. They only support relative paths for our own modules, and paths for the node_modules folder. When a project grows a bit, it’s common to see paths such:
在Js社區(qū)內(nèi)我們可以用的模塊管理工具,比如ES模塊化或者CommonJS,都不太支持基于項(xiàng)目目錄的路徑,而是僅支持我們自己模塊的相對(duì)路徑,以及node_modules文件夾。如果項(xiàng)目結(jié)構(gòu)越來(lái)越復(fù)雜,我們可能會(huì)看到如下長(zhǎng)長(zhǎng)的路徑:

import SomeComponent from '../../../../components/SomeComponent'

Luckily, we have different ways to cope with this, in a way that we can define aliases for folders relative to the project root, so we could the above line like:
還好,我們有各種方法來(lái)應(yīng)對(duì)這種情況,一種方法就是我們?cè)O(shè)置某些相對(duì)于根目錄的文件夾的別名,就像上面的引用,就可以變?yōu)槿缦卤硎荆?/p>

import SomeComponent from '@/components/SomeComponent'

The @ here is an arbitrary character to define the root project, you can define your own. Let’s see what solutions we have to apply module aliasing. Let’s start from where we left it on the last article.
這里的@符號(hào)是定義項(xiàng)目根目錄的字符,你也可以定制自己想要的別名。來(lái)看一下我們?nèi)绾卧O(shè)置模塊別名,這就是我們最后一篇文章要講的。

Webpack aliases

Webpack別名

Webpack aliases are very simple to set up. You just need to add a resolve.alias property in your webpack configuration. If you take a look at the build/webpack.base.conf.js, it already has it defined:
Webpack的別名設(shè)置非常簡(jiǎn)單。你只需要在配置文件中的resolve.alias里設(shè)置,文件路徑是build/webpack.base.conf.js。

{
  ...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
    }
  }
}

Taking this as an entry point, we can add a simple alias that points to the src folder and use that as the root:
以此為切入點(diǎn),我們可以添加一些簡(jiǎn)單的別名,指向根目錄中的src文件夾:

{
  ...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': path.join(__dirname, '..', 'src')
    }
  }
}

Just with this, we can access anything taking the root project as the @ symbol. Let’s go to src/App.vue and change the reference to those two components:
這樣設(shè)置以后,我們可以訪(fǎng)問(wèn)到任何資源通過(guò)@標(biāo)識(shí)符。我們?cè)囍眯路椒ㄒ觅Y源:

  import MessageList from '@/components/MessageList'
  import Message from '@/components/Message'
  ...

And if we run npm start and open the browser at localhost:8080, that should work out of the box.
如果我們啟動(dòng)npm的服務(wù),打開(kāi)瀏覽器訪(fǎng)問(wèn)localhost:8080,可以發(fā)現(xiàn)之前的設(shè)置已經(jīng)生效了。

However, if we try to run the tests by running npm t, we’ll see Jest doesn’t find the modules. We still didn’t configured Jest to do so. So let’s go to package.json where the Jest config is, and add "@/([^\\.]*)$": "<rootDir>/src/$1" to moduleNameMapper:
但是,如果我們嘗試執(zhí)行測(cè)試用例,運(yùn)行npm t后,我們可以看到Jest報(bào)錯(cuò)說(shuō)沒(méi)有找到相關(guān)模塊。我們至今還沒(méi)搞清楚為什么Jest不支持這種配置。為了解決這個(gè)問(wèn)題,我們?nèi)?code>package.json中的Jest配置內(nèi)容里添加一段代碼:"@/([^\\.]*)$": "<rootDir>/src/$1" to moduleNameMapper:

    "jest": {
        "moduleNameMapper": {
          "@(.*)$": "<rootDir>/src/$1",
          "^vue$": "vue/dist/vue.common.js"
        }
    }
...

Let’s explain it:
讓我解釋下這段代碼的用處:

@(.*)$: Whatever starts with @, and continues with literally whatever ((.*)$) till the end of the string, grouping it by using the parenthesis
@(.*)$:無(wú)論什么路徑,只要以@開(kāi)頭,并且后面以((.*)$)結(jié)尾,這里使用括號(hào)對(duì)其進(jìn)行正則分組。

<rootDir>/src/$1: <rootDir> is a special word of Jest, meaning the root directory. Then we map it to the src, and with 1 we append the whatever clause from the `(.*)` statement. `/src/1:其中<rootDir>是Jest中的一個(gè)關(guān)鍵字,代表著根目錄。然后我們映射到src目錄,并且$1代表著與前文中(.*)`匹配的分組。

For example, @/components/MessageList will be mapped to ../src/components/MessageList when you’re importing it from the src or test folders.
例如,當(dāng)我們引入src或者test文件夾中的資源時(shí),@/components/MessageList等價(jià)于../src/components/MessageList。

That’s really it. Now you can even update your App.test.jsfile to use the alias as well, since it’s usable from within the tests:
用法就是這樣?,F(xiàn)在我們可以用別名的方式更新App.test.js文件了:

import { shallow } from "vue-test-utils"
import App from "@/App"
...

And it will work for both .vue and .js files.
這種方式對(duì)vue和js格式的文件都有效。

Multiple aliases

多個(gè)別名

Very often, multiple aliases are used for convenience, so instead of using just a @ to define your root folder, you use many. For example, let’s say you have a actions and models folder. If you create an alias for each one, and then you move the folders around, you just need to change the aliases instead of updating all the references to it in the codebase. That’s the power of module aliases, they make your codebase more maintainable and cleaner.
通常我們不會(huì)只用@來(lái)索引資源,我們可以設(shè)置多個(gè)別名來(lái)更方便的引入模塊。舉個(gè)例子,比如說(shuō)你有一個(gè)actions和models的文件夾。如果你對(duì)他們分別設(shè)置別名,然后你挪動(dòng)了文件夾,這時(shí)你只需要在配置文件中修改一次別名引用地址,就不用在代碼中修復(fù)海量的引用地址的指向了。這就是模塊別名的妙用。

Let’s add a components alias in build/webpack.base.conf.js:
讓我們?cè)?code>build/webpack.base.conf.js中添加components文件夾的別名。

{
  ...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': path.join(__dirname, '..', 'src')
      'components': path.join(__dirname, '..', 'src', 'components')
    }
  }
}

Then, we just need to add it as well to the Jest configuration in package.json:
然后我們只需要package.json中再次添加一些配置:

"jest": {
    "moduleNameMapper": {
      "@(.*)$": "<rootDir>/src/$1",
      "components(.*)$": "<rootDir>/src/components/$1",
      "^vue$": "vue/dist/vue.common.js"
    }
}
...

As simple as that. Now, we can try in App.vue to use both forms:
就這么簡(jiǎn)單?,F(xiàn)在我們?cè)贏pp組件中試下這兩種方式:

import MessageList from 'components/MessageList'
import Message from '@/components/Message'

Stop and re-run the tests, and that should work, as well as if you run npm start and try it.
不要反復(fù)試了,這兩個(gè)方法都能生效。

Other solutions

其他解決辦法

I’ve seen babel-plugin-webpack-alias, specially used for other testing frameworks such as mocha which doesn’t have a module mapper.
我已經(jīng)調(diào)研過(guò)babel-plugin-webpack-alias了,特別是用在其他測(cè)試框架中,比如mocha等不支持模塊映射的框架。

I haven’t tried it myself, since Jest already gives you that, but if you have or wanna try, please share how it went!
我沒(méi)有親自試,因?yàn)镴est已經(jīng)提供這些功能了,但是如果你還是想親自嘗試一下,可以給大家分享一下!

Conclusion

總結(jié)

Adding module aliases is very simple and can keep your codebase much cleaner and easier to maintain. Jest makes it as well very easy to define them, you just need to keep in in sync with the Webpack aliases, and you can say bye-bye to the dot-hell references.
添加模塊別名非常簡(jiǎn)單,而且可以讓你的代碼簡(jiǎn)潔高效。Jest讓我們很簡(jiǎn)便地定義別名,你只需要讓Jest和Webpack同步別名的設(shè)置,你就可以跟見(jiàn)鬼的'點(diǎn)點(diǎn)式'引用說(shuō)拜拜了!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容