diff --git a/.gitignore b/.gitignore index 2840708..9b0a993 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ npm-debug.log _book/ demo/*/node_modules demo/*/npm-debug.log +demo/*/package-lock.json demo/*/upload-files/ demo/upload-async/static/image/ diff --git a/demo/esm/custom-loader.mjs b/demo/esm/custom-loader.mjs new file mode 100644 index 0000000..2678fbf --- /dev/null +++ b/demo/esm/custom-loader.mjs @@ -0,0 +1,72 @@ +import url from 'url'; +import path from 'path'; +import process from 'process'; +import fs from 'fs'; + +// 从package.json中 +// 的dependencies、devDependencies获取项目所需npm模块信息 +const ROOT_PATH = process.cwd(); +const PKG_JSON_PATH = path.join( ROOT_PATH, 'package.json' ); +const PKG_JSON_STR = fs.readFileSync(PKG_JSON_PATH, 'binary'); +const PKG_JSON = JSON.parse(PKG_JSON_STR); +// 项目所需npm模块信息 +const allDependencies = { + ...PKG_JSON.dependencies || {}, + ...PKG_JSON.devDependencies || {} +} + +//Node原生模信息 +const builtins = new Set( + Object.keys(process.binding('natives')).filter((str) => + /^(?!(?:internal|node|v8)\/)/.test(str)) +); + +// 文件引用兼容后缀名 +const JS_EXTENSIONS = new Set(['.js', '.mjs']); +const JSON_EXTENSIONS = new Set(['.json']); + +export function resolve(specifier, parentModuleURL, defaultResolve) { + // 判断是否为Node原生模块 + if (builtins.has(specifier)) { + return { + url: specifier, + format: 'builtin' + }; + } + + // 判断是否为npm模块 + if ( allDependencies && typeof allDependencies[specifier] === 'string' ) { + return defaultResolve(specifier, parentModuleURL); + } + + // 如果是文件引用,判断是否路径格式正确 + if (/^\.{0,2}[/]/.test(specifier) !== true && !specifier.startsWith('file:')) { + throw new Error( + `imports must begin with '/', './', or '../'; '${specifier}' does not`); + } + + // 判断是否为*.js、*.mjs、*.json文件 + const resolved = new url.URL(specifier, parentModuleURL); + const ext = path.extname(resolved.pathname); + if (!JS_EXTENSIONS.has(ext) && !JSON_EXTENSIONS.has(ext)) { + throw new Error( + `Cannot load file with non-JavaScript file extension ${ext}.`); + } + + // 如果是*.js、*.mjs文件 + if (JS_EXTENSIONS.has(ext)) { + return { + url: resolved.href, + format: 'esm' + }; + } + + // 如果是*.json文件 + if (JSON_EXTENSIONS.has(ext)) { + return { + url: resolved.href, + format: 'json' + }; + } + +} \ No newline at end of file diff --git a/demo/esm/index.js b/demo/esm/index.js new file mode 100644 index 0000000..28e7504 --- /dev/null +++ b/demo/esm/index.js @@ -0,0 +1,20 @@ +import Koa from 'koa'; +import { render } from './lib/render.js'; +import data from './lib/data.json'; + +let app = new Koa(); +app.use((ctx, next) => { + let view = ctx.url.substr(1); + let content; + if ( view === '' ) { + content = render('index'); + } else if ( view === 'data' ) { + content = data; + } else { + content = render(view); + } + ctx.body = content; +}) +app.listen(3000, ()=>{ + console.log('the modules test server is starting'); +}) \ No newline at end of file diff --git a/demo/esm/lib/data.json b/demo/esm/lib/data.json new file mode 100644 index 0000000..126283b --- /dev/null +++ b/demo/esm/lib/data.json @@ -0,0 +1,4 @@ +{ + "title": "hello ES6 Modules", + "name": "ES6" +} \ No newline at end of file diff --git a/demo/esm/lib/path.js b/demo/esm/lib/path.js new file mode 100644 index 0000000..77c4799 --- /dev/null +++ b/demo/esm/lib/path.js @@ -0,0 +1,3 @@ +import process from 'process'; + +export const PROJECT_PATH = process.cwd(); \ No newline at end of file diff --git a/demo/esm/lib/render.js b/demo/esm/lib/render.js new file mode 100644 index 0000000..8ed9589 --- /dev/null +++ b/demo/esm/lib/render.js @@ -0,0 +1,12 @@ +import { PROJECT_PATH } from './path.js'; +import fs from 'fs'; +import path from 'path' + +export const render = ( view ) => { + let viewPath = path.join(PROJECT_PATH, 'view',`${view}.html`); + if ( fs.existsSync(viewPath) ) { + return fs.readFileSync(viewPath, 'binary'); + } else { + return `Error: file ${view}.html is not found!`; + } +} \ No newline at end of file diff --git a/demo/esm/package.json b/demo/esm/package.json new file mode 100644 index 0000000..3ce1d45 --- /dev/null +++ b/demo/esm/package.json @@ -0,0 +1,20 @@ +{ + "name": "demo1", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node --experimental-modules --loader ./custom-loader.mjs ./index.js" + }, + "author": "", + "license": "MIT", + "engines": { + "node": ">= 9.0.0" + }, + "dependencies": { + "koa": "^2.4.1" + }, + "devDependencies": { + "eslint": "^4.11.0" + } +} diff --git a/demo/esm/view/helloworld.html b/demo/esm/view/helloworld.html new file mode 100644 index 0000000..f52c9e0 --- /dev/null +++ b/demo/esm/view/helloworld.html @@ -0,0 +1,8 @@ + + + hello world + + +

hello world page

+ + \ No newline at end of file diff --git a/demo/esm/view/index.html b/demo/esm/view/index.html new file mode 100644 index 0000000..8d65f66 --- /dev/null +++ b/demo/esm/view/index.html @@ -0,0 +1,19 @@ + + + index + + +

hello world

+ + + \ No newline at end of file diff --git a/demo/esm/view/todo.html b/demo/esm/view/todo.html new file mode 100644 index 0000000..ef290c5 --- /dev/null +++ b/demo/esm/view/todo.html @@ -0,0 +1,8 @@ + + + todo + + +

todo page

+ + \ No newline at end of file