龙空技术网

「3mins」四条写JS模块的最佳实践

D瓊 275

前言:

现时同学们对“js绝对路径怎么写”都比较重视,我们都想要了解一些“js绝对路径怎么写”的相关知识。那么小编在网络上收集了一些有关“js绝对路径怎么写””的相关资讯,希望看官们能喜欢,姐妹们一起来了解一下吧!

一 、 最好使用命名好的exports,而不是default

在写模块输出的时候,有时候我们会这样写:

// greeter.jsexport default class Greeter {  constructor(name) {    this.name = name;  }  greet() {    return `Hello, ${this.name}!`;  }}

引用处就可以这样写

import Greeter from 'greeter.js'

这么写的弊端是,如果需要万一有一天这个方法要重构,需要重新改一个名字,变成SayHello,那么在使用处就需要你自己一处处去找来改这个名字。

但是如果你export出来的就是一个命名的函数

// greeter.jsexport class Greeter {  constructor(name) {    this.name = name;  }  greet() {    return `Hello, ${this.name}!`;  }}

这样引用处就会这样引用

import { Greeter } from 'greeter.js'

这样每当你去改Greeter的名字的时候,编辑器vscode就会帮你自动把引用的地方都改成SayHello。

二、不要在export的函数做复杂计算

不要在export的函数做复杂计算例如:解析json,发送http请求,读本地local Storage的数据等等。

比如:下面这个模块中,export一个configuration模块,里面去解析了一个大的JSON字符串。

// configuration.jsexport const configuration = {  // Bad  data: JSON.parse(bigJsonString)};

那么在引用的地方,import configuration的时候,这个解析json的东西就已经被执行了。所以可能会拖慢JS执行的速度,从而拖慢用户的可交互时间。

// Bad: parsing happens when the module is importedimport { configuration } from 'configuration';export function AboutUs() {  return <p>{configuration.data.siteName}</p>;}

好的实践当然是等到用的时候再去执行这个复杂计算,所以我们来重构一下这个代码。

// configuration.jslet parsedData = null;export const configuration = {  // Good  get data() {    if (parsedData === null) {      parsedData = JSON.parse(bigJsonString);    }    return parsedData;  }};

由于data已经被定义成一个getter,所以只会在用户真正用到configuration.data的时候才去解析大的json字符串。

// Good: JSON parsing doesn't happen when the module is importedimport { configuration } from 'configuration';export function AboutUs() {  // JSON parsing happens now  return <p>{configuration.data.companyDescription}</p>;}

在真正用到的时候才去执行这些复杂计算就可以防止有时候只是加载进来,却没有使用,造成计算浪费。而且还可以做网站的性能优化,在浏览器处于空闲时候才去执行这些复杂操作。

三、写高关联的模块

要求模块里的东西都是互相关联的,他们密切相关,公共合作处理同一个任务。

比如这个模块 formatDate就是高关联的,因为MONTHS,ensureDateInstance,formatDate相互关联,只做一个任务就是日期格式化。删除MONTHS或者ensureDateInstance都会使得最后export出去的formatDate无法正常工作。

// formatDate.jsconst MONTHS = [  'January', 'February', 'March','April', 'May',  'June', 'July', 'August', 'September', 'October',  'November', 'December'];function ensureDateInstance(date) {  if (typeof date === 'string') {    return new Date(date);  }  return date;}export function formatDate(date) {  date = ensureDateInstance(date);  const monthName = MONTHS[date.getMonth())];  return `${monthName} ${date.getDate()}, ${date.getFullYear()}`;}

在来一个反例:

// utils.jsimport cookies from 'cookies';export function getRandomInRange(start, end) {  return start + Math.floor((end - start) * Math.random());}export function pluralize(itemName, count) {  return count > 1 ? `${itemName}s` : itemName;}export function cookieExists(cookieName) {  const cookiesObject = cookie.parse(document.cookie);  return cookieName in cookiesObject;}

在这里例子中,这三个函数都在做不同的任务。大家都跟彼此毫无联系,三个函数中即使少掉其中任意一个,对其他两个函数都没有什么大的影响,这就是低关联的表现。

低关联有个不好的地方就是有可能会引入进来这个函数根本用不到的模块。

比如,我要使用utils 里的pluralize

// ShoppingCartCount.jsximport { pluralize } from 'utils';export function ShoppingCartCount({ count }) {  return (    <div>      Shopping cart has {count} {pluralize('product', count)}    </div>  );}

但是由于utils里还引用了cookies,所以即使pluralize里根本没有用到这个模块,cookies也被引用了进来,造成冗余。

好的实践是将他们分开成高关联的模块:utils/random,utils/stringFormatandutils/cookies。

这样,当ShoppingCart 去引用utils/stringFormat的时候,就不会引入进来无用的模块。

// ShoppingCartCount.jsximport { pluralize } from 'utils/stringFormat';export function ShoppingCartCount({ count }) {  // ...}  
四、避免长的相对路径
import { compareDates } from '../../date/compare';import { formatDate }   from '../../date/format';

../ 超过两个就比较难去找在哪个层级了。所以最好还是不要这样写, 直接写绝对路径。

import { compareDates } from 'utils/date/compare';import { formatDate }   from 'utils/date/format';

这样不仅更易书写,同时也更好找这个引用模块的未知。

原文链接:

4 Best Practices to Write Quality JavaScript Modules​dmitripavlutin.com

标签: #js绝对路径怎么写