Commonjs和ECMAScript语法
Commonjs
Nodejs中默认采用Commonjs语法。
模块导出格式如下。
1 2 3 4 module .exports = { setResHeader : setResHeader }
模块导入格式如下。
1 2 let resHeaderUtil = require ("./utils/resHeaderUtil" )
ECMAScript
比如vue这种框架,采用的就是ECMAScript语法。要使用这种语法,首先得在package.json中指出type的值。
When set to “module”, the type field allows a package to specify all .js files within are ES modules. If the “type” field is omitted or set to “commonjs”, all .js files are treated as CommonJS.
这便设置成了。
默认导出
1 2 3 4 export default { setResHeader : setResHeader }
当我们需要时,如下导入即可。
1 2 import resHeaderUtil from './utils/resHeaderUtil-ecmascript-default.js'
命名导出
只需要在变量前面加上 export 修饰,即可在其它地方导入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 export function setResHeader (response, contentType ) { if (contentType == "html" ) response.setHeader ("Content-Type" , "text/html;charset=utf-8" ); else if (contentType == "css" ) response.setHeader ("Content-Type" , "text/css;charset=utf-8" ); else if (contentType == "js" ) response.setHeader ("Content-Type" , "application/javascript;charset=utf-8" ); else response.setHeader ("Content-Type" , "text/plain;charset=utf-8" ); }
命名导出方式,在导入时,是按需导入,按需加载。花括号中放置需要的变量,不用像默认导出那样将整个模块都导入进来。
需要注意的是,花括号中的变量名,要和引入模块中的变量名或者函数名相同。
1 2 import { setResHeader } from './utils/resHeaderUtil-ecmascript-named.js'
语法差异
在Common.js中,我们可以使用__dirname来获取当前js文件所在目录的绝对路径,通过node:path模块的join方法来拼接自己想要的绝对路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server.on ("request" , (req, res ) => { let pathname = req.url var postfix = pathname.match (/(\.[^.]+|)$/ )[0 ]; let filePath = path.join (__dirname, "./Login" , pathname) fs.readFile (filePath, (err, data ) => { if (err) { res.setHeader ("Content-Type" , "text/html;charset=utf-8" ) res.end ("<h1>访问的内容不存在</h1>" ) } else { if (postfix == "html" ) resHeaderUtil.setResHeader (res, "html" ) else if (postfix == "css" ) resHeaderUtil.setResHeader (res, "css" ) else if (postfix == "js" ) resHeaderUtil.setResHeader (res, "js" ) res.end (data.toString ()) } }) })
但是当我们使用ES语法后,__dirname就不能使用了,否则会报错如下。
ReferenceError: __dirname is not defined in ES module scope
但是我们使用fs.readFile方法时,又经常需要使用到绝对路径。作为__dirname的替代方案,可以实现工具类如下。
1 2 3 4 5 6 7 8 9 10 11 import url from 'node:url' import path from 'node:path' export function getRecentDir (fileUrl ) { let filePath = url.fileURLToPath (fileUrl) let dirname = path.dirname (filePath) return dirname }
外界传入对应的文件URL即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import { setResHeader } from './utils/resHeaderUtil-ecmascript-named.js' import { getRecentDir } from './utils/recentPath.js' server.on ("request" , (req, res ) => { let pathname = req.url var postfix = pathname.match (/(\.[^.]+|)$/ )[0 ]; let filePath = path.join (getRecentDir (import .meta .url ), "./Login" , pathname) fs.readFile (filePath, (err, data ) => { if (err) { res.setHeader ("Content-Type" , "text/html;charset=utf-8" ) res.end ("<h1>访问的内容不存在</h1>" ) } else { if (postfix == "html" ) setResHeader (res, "html" ) else if (postfix == "css" ) setResHeader (res, "css" ) else if (postfix == "js" ) setResHeader (res, "js" ) res.end (data.toString ()) } }) })