mirror of https://gitee.com/antv-l7/antv-l7
refactor(cache): rm .cache and public
This commit is contained in:
parent
d8967f2b45
commit
b91c81afd9
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"globals": {
|
||||
"__PATH_PREFIX__": false,
|
||||
"___emitter": false
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"presets": [
|
||||
["babel-preset-gatsby"]
|
||||
]
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Dev loader loadPage should be successful when component can be loaded 1`] = `
|
||||
Object {
|
||||
"component": "instance",
|
||||
"json": Object {
|
||||
"pageContext": "something something",
|
||||
},
|
||||
"page": Object {
|
||||
"componentChunkName": "chunk",
|
||||
"matchPath": undefined,
|
||||
"path": "/mypage/",
|
||||
"webpackCompilationHash": "123",
|
||||
},
|
||||
}
|
||||
`;
|
|
@ -1,16 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Production loader loadPage should be successful when component can be loaded 1`] = `
|
||||
Object {
|
||||
"component": "instance",
|
||||
"json": Object {
|
||||
"pageContext": "something something",
|
||||
},
|
||||
"page": Object {
|
||||
"componentChunkName": "chunk",
|
||||
"matchPath": undefined,
|
||||
"path": "/mypage/",
|
||||
"webpackCompilationHash": "123",
|
||||
},
|
||||
}
|
||||
`;
|
|
@ -1,13 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`develop-static-entry onPreRenderHTML can be used to replace headComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><style> .style3 </style><style> .style2 </style><style> .style1 </style><meta name=\\"note\\" content=\\"environment=development\\"/><script src=\\"/socket.io/socket.io.js\\"></script></head><body><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"></div><script src=\\"/commons.js\\"></script></body></html>"`;
|
||||
|
||||
exports[`develop-static-entry onPreRenderHTML can be used to replace postBodyComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><meta name=\\"note\\" content=\\"environment=development\\"/><script src=\\"/socket.io/socket.io.js\\"></script></head><body><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"></div><div> div3 </div><div> div2 </div><div> div1 </div><script src=\\"/commons.js\\"></script></body></html>"`;
|
||||
|
||||
exports[`develop-static-entry onPreRenderHTML can be used to replace preBodyComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><meta name=\\"note\\" content=\\"environment=development\\"/><script src=\\"/socket.io/socket.io.js\\"></script></head><body><div> div3 </div><div> div2 </div><div> div1 </div><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"></div><script src=\\"/commons.js\\"></script></body></html>"`;
|
||||
|
||||
exports[`static-entry onPreRenderHTML can be used to replace headComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><link as=\\"fetch\\" rel=\\"preload\\" href=\\"/page-data/about/page-data.json\\" crossorigin=\\"anonymous\\"/><style> .style3 </style><style> .style2 </style><style> .style1 </style><meta name=\\"generator\\" content=\\"Gatsby 2.0.0\\"/></head><body><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"><div style=\\"outline:none\\" tabindex=\\"-1\\" role=\\"group\\" id=\\"gatsby-focus-wrapper\\"></div></div><script id=\\"gatsby-script-loader\\">/*<![CDATA[*/window.pagePath=\\"/about/\\";/*]]>*/</script><script id=\\"gatsby-chunk-mapping\\">/*<![CDATA[*/window.___chunkMapping={};/*]]>*/</script></body></html>"`;
|
||||
|
||||
exports[`static-entry onPreRenderHTML can be used to replace postBodyComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><meta name=\\"generator\\" content=\\"Gatsby 2.0.0\\"/><link as=\\"fetch\\" rel=\\"preload\\" href=\\"/page-data/about/page-data.json\\" crossorigin=\\"anonymous\\"/></head><body><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"><div style=\\"outline:none\\" tabindex=\\"-1\\" role=\\"group\\" id=\\"gatsby-focus-wrapper\\"></div></div><script id=\\"gatsby-chunk-mapping\\">/*<![CDATA[*/window.___chunkMapping={};/*]]>*/</script><script id=\\"gatsby-script-loader\\">/*<![CDATA[*/window.pagePath=\\"/about/\\";/*]]>*/</script><div> div3 </div><div> div2 </div><div> div1 </div></body></html>"`;
|
||||
|
||||
exports[`static-entry onPreRenderHTML can be used to replace preBodyComponents 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><meta name=\\"generator\\" content=\\"Gatsby 2.0.0\\"/><link as=\\"fetch\\" rel=\\"preload\\" href=\\"/page-data/about/page-data.json\\" crossorigin=\\"anonymous\\"/></head><body><div> div3 </div><div> div2 </div><div> div1 </div><noscript id=\\"gatsby-noscript\\">This app works best with JavaScript enabled.</noscript><div id=\\"___gatsby\\"><div style=\\"outline:none\\" tabindex=\\"-1\\" role=\\"group\\" id=\\"gatsby-focus-wrapper\\"></div></div><script id=\\"gatsby-script-loader\\">/*<![CDATA[*/window.pagePath=\\"/about/\\";/*]]>*/</script><script id=\\"gatsby-chunk-mapping\\">/*<![CDATA[*/window.___chunkMapping={};/*]]>*/</script></body></html>"`;
|
|
@ -1,539 +0,0 @@
|
|||
// This is by no means a full test file for loader.js so feel free to add more tests.
|
||||
import mock from "xhr-mock"
|
||||
import DevLoader from "../dev-loader"
|
||||
import emitter from "../emitter"
|
||||
|
||||
jest.mock(`../emitter`)
|
||||
jest.mock(`../socketIo`, () => {
|
||||
return {
|
||||
default: jest.fn(),
|
||||
getPageData: jest.fn().mockResolvedValue(),
|
||||
}
|
||||
})
|
||||
|
||||
describe(`Dev loader`, () => {
|
||||
describe(`loadPageDataJson`, () => {
|
||||
let originalBasePath
|
||||
let originalPathPrefix
|
||||
let xhrCount
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {number} status
|
||||
* @param {string|Object?} responseText
|
||||
* @param {boolean?} json
|
||||
*/
|
||||
const mockPageData = (path, status, responseText = ``, json = false) => {
|
||||
mock.get(`/page-data${path}/page-data.json`, (req, res) => {
|
||||
xhrCount++
|
||||
if (json) {
|
||||
res.header(`content-type`, `application/json`)
|
||||
}
|
||||
|
||||
return res
|
||||
.status(status)
|
||||
.body(
|
||||
typeof responseText === `string`
|
||||
? responseText
|
||||
: JSON.stringify(responseText)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const defaultPayload = {
|
||||
path: `/mypage/`,
|
||||
}
|
||||
|
||||
// replace the real XHR object with the mock XHR object before each test
|
||||
beforeEach(() => {
|
||||
originalBasePath = global.__BASE_PATH__
|
||||
originalPathPrefix = global.__PATH_PREFIX__
|
||||
global.__BASE_PATH__ = ``
|
||||
global.__PATH_PREFIX__ = ``
|
||||
xhrCount = 0
|
||||
mock.setup()
|
||||
})
|
||||
|
||||
// put the real XHR object back and clear the mocks after each test
|
||||
afterEach(() => {
|
||||
global.__BASE_PATH__ = originalBasePath
|
||||
global.__PATH_PREFIX__ = originalPathPrefix
|
||||
mock.teardown()
|
||||
})
|
||||
|
||||
it(`should return a pageData json on success`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload: defaultPayload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(devLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should return a pageData json on success without contentType`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload: defaultPayload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(devLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should return a pageData json with an empty compilation hash (gatsby develop)`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, webpackCompilationHash: `` }
|
||||
mockPageData(`/mypage`, 200, payload)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(devLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when page-path file is not a gatsby json`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200, { random: `string` }, true)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when page-path file is not a json`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when path returns a 404`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should return the dev-404-page when no 404 page can be found`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/dev-404-page/` }
|
||||
mockPageData(`/unknown-page`, 404)
|
||||
mockPageData(`/404.html`, 404)
|
||||
mockPageData(`/dev-404-page`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/dev-404-page`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
|
||||
expect(devLoader.pageDataDb.get(`/unknown-page`)).toEqual({
|
||||
notFound: true,
|
||||
pagePath: `/404.html`,
|
||||
status: `failure`,
|
||||
})
|
||||
expect(xhrCount).toBe(3)
|
||||
})
|
||||
|
||||
it(`should return an error when status is 500`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
mockPageData(`/error-page`, 500)
|
||||
|
||||
const expectation = {
|
||||
status: `error`,
|
||||
pagePath: `/error-page`,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/error-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/error-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should retry 3 times before returning an error`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
mockPageData(`/blocked-page`, 0)
|
||||
|
||||
const expectation = {
|
||||
status: `error`,
|
||||
retries: 3,
|
||||
pagePath: `/blocked-page`,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/blocked-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/blocked-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(4)
|
||||
})
|
||||
|
||||
it(`should recover if we get 1 failure`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
const payload = {
|
||||
path: `/blocked-page/`,
|
||||
}
|
||||
|
||||
let xhrCount = 0
|
||||
mock.get(`/page-data/blocked-page/page-data.json`, (req, res) => {
|
||||
if (xhrCount++ === 0) {
|
||||
return res.status(0).body(``)
|
||||
} else {
|
||||
res.header(`content-type`, `application/json`)
|
||||
return res.status(200).body(JSON.stringify(payload))
|
||||
}
|
||||
})
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
retries: 1,
|
||||
pagePath: `/blocked-page`,
|
||||
payload,
|
||||
}
|
||||
expect(await devLoader.loadPageDataJson(`/blocked-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(devLoader.pageDataDb.get(`/blocked-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`shouldn't load pageData multiple times`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload, true)
|
||||
|
||||
const expectation = await devLoader.loadPageDataJson(`/mypage/`)
|
||||
expect(await devLoader.loadPageDataJson(`/mypage/`)).toBe(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe(`loadPage`, () => {
|
||||
const createSyncRequires = components => {
|
||||
return {
|
||||
components,
|
||||
}
|
||||
}
|
||||
|
||||
let originalPathPrefix
|
||||
|
||||
beforeEach(() => {
|
||||
originalPathPrefix = global.__PATH_PREFIX__
|
||||
global.__PATH_PREFIX__ = ``
|
||||
mock.setup()
|
||||
mock.get(`/page-data/app-data.json`, (req, res) =>
|
||||
res
|
||||
.status(200)
|
||||
.header(`content-type`, `application/json`)
|
||||
.body(
|
||||
JSON.stringify({
|
||||
webpackCompilationHash: `123`,
|
||||
})
|
||||
)
|
||||
)
|
||||
emitter.emit.mockReset()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
global.__PATH_PREFIX__ = originalPathPrefix
|
||||
mock.teardown()
|
||||
})
|
||||
|
||||
it(`should be successful when component can be loaded`, async () => {
|
||||
const syncRequires = createSyncRequires({
|
||||
chunk: `instance`,
|
||||
})
|
||||
const devLoader = new DevLoader(syncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
result: {
|
||||
pageContext: `something something`,
|
||||
},
|
||||
}
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
const expectation = await devLoader.loadPage(`/mypage/`)
|
||||
expect(expectation).toMatchSnapshot()
|
||||
expect(Object.keys(expectation)).toEqual([`component`, `json`, `page`])
|
||||
expect(devLoader.pageDb.get(`/mypage`)).toEqual(
|
||||
expect.objectContaining({
|
||||
payload: expectation,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(1)
|
||||
expect(emitter.emit).toHaveBeenCalledWith(`onPostLoadPageResources`, {
|
||||
page: expectation,
|
||||
pageResources: expectation,
|
||||
})
|
||||
})
|
||||
|
||||
it(`should set not found on finalResult`, async () => {
|
||||
const syncRequires = createSyncRequires({
|
||||
chunk: `instance`,
|
||||
})
|
||||
const devLoader = new DevLoader(syncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
notFound: true,
|
||||
})
|
||||
)
|
||||
|
||||
await devLoader.loadPage(`/mypage/`)
|
||||
const expectation = devLoader.pageDb.get(`/mypage`)
|
||||
expect(expectation).toHaveProperty(`notFound`, true)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(1)
|
||||
expect(emitter.emit).toHaveBeenCalledWith(`onPostLoadPageResources`, {
|
||||
page: expectation.payload,
|
||||
pageResources: expectation.payload,
|
||||
})
|
||||
})
|
||||
|
||||
it(`should return an error when component cannot be loaded`, async () => {
|
||||
const syncRequires = createSyncRequires({
|
||||
chunk: false,
|
||||
})
|
||||
const devLoader = new DevLoader(syncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
await devLoader.loadPage(`/mypage/`)
|
||||
const expectation = devLoader.pageDb.get(`/mypage`)
|
||||
expect(expectation).toHaveProperty(`status`, `error`)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should return an error pageData contains an error`, async () => {
|
||||
const syncRequires = createSyncRequires({
|
||||
chunk: `instance`,
|
||||
})
|
||||
const devLoader = new DevLoader(syncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `error`,
|
||||
})
|
||||
)
|
||||
|
||||
expect(await devLoader.loadPage(`/mypage/`)).toEqual({ status: `error` })
|
||||
expect(devLoader.pageDb.size).toBe(0)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should throw an error when 404 cannot be fetched`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
status: `failure`,
|
||||
})
|
||||
)
|
||||
|
||||
try {
|
||||
await devLoader.loadPage(`/404.html/`)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
expect.stringContaining(`404 page could not be found`)
|
||||
)
|
||||
}
|
||||
expect(devLoader.pageDb.size).toBe(0)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should cache the result of loadPage`, async () => {
|
||||
const syncRequires = createSyncRequires({
|
||||
chunk: `instance`,
|
||||
})
|
||||
const devLoader = new DevLoader(syncRequires, [])
|
||||
devLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: {
|
||||
componentChunkName: `chunk`,
|
||||
},
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
const expectation = await devLoader.loadPage(`/mypage/`)
|
||||
expect(await devLoader.loadPage(`/mypage/`)).toBe(expectation)
|
||||
expect(devLoader.loadPageDataJson).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe(`loadPageSync`, () => {
|
||||
it(`returns page resources when already fetched`, () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
devLoader.pageDb.set(`/mypage`, { payload: true })
|
||||
expect(devLoader.loadPageSync(`/mypage/`)).toBe(true)
|
||||
})
|
||||
|
||||
it(`returns page resources when already fetched`, () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
|
||||
expect(devLoader.loadPageSync(`/mypage/`)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe(`prefetch`, () => {
|
||||
const flushPromises = () => new Promise(resolve => setImmediate(resolve))
|
||||
|
||||
it(`shouldn't prefetch when shouldPrefetch is false`, () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
devLoader.shouldPrefetch = jest.fn(() => false)
|
||||
devLoader.doPrefetch = jest.fn()
|
||||
devLoader.apiRunner = jest.fn()
|
||||
|
||||
expect(devLoader.prefetch(`/mypath/`)).toBe(false)
|
||||
expect(devLoader.shouldPrefetch).toHaveBeenCalledWith(`/mypath/`)
|
||||
expect(devLoader.apiRunner).not.toHaveBeenCalled()
|
||||
expect(devLoader.doPrefetch).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it(`should trigger custom prefetch logic when core is disabled`, () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
devLoader.shouldPrefetch = jest.fn(() => true)
|
||||
devLoader.doPrefetch = jest.fn()
|
||||
devLoader.apiRunner = jest.fn()
|
||||
devLoader.prefetchDisabled = true
|
||||
|
||||
expect(devLoader.prefetch(`/mypath/`)).toBe(false)
|
||||
expect(devLoader.shouldPrefetch).toHaveBeenCalledWith(`/mypath/`)
|
||||
expect(devLoader.apiRunner).toHaveBeenCalledWith(`onPrefetchPathname`, {
|
||||
pathname: `/mypath/`,
|
||||
})
|
||||
expect(devLoader.doPrefetch).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it(`should prefetch when not yet triggered`, async () => {
|
||||
jest.useFakeTimers()
|
||||
const devLoader = new DevLoader(null, [])
|
||||
devLoader.shouldPrefetch = jest.fn(() => true)
|
||||
devLoader.apiRunner = jest.fn()
|
||||
devLoader.doPrefetch = jest.fn(() => Promise.resolve({}))
|
||||
|
||||
expect(devLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
|
||||
// wait for doPrefetchPromise
|
||||
await flushPromises()
|
||||
|
||||
expect(devLoader.apiRunner).toHaveBeenCalledWith(`onPrefetchPathname`, {
|
||||
pathname: `/mypath/`,
|
||||
})
|
||||
expect(devLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
`onPostPrefetchPathname`,
|
||||
{
|
||||
pathname: `/mypath/`,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it(`should only run apis once`, async () => {
|
||||
const devLoader = new DevLoader(null, [])
|
||||
devLoader.shouldPrefetch = jest.fn(() => true)
|
||||
devLoader.apiRunner = jest.fn()
|
||||
devLoader.doPrefetch = jest.fn(() => Promise.resolve({}))
|
||||
|
||||
expect(devLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
expect(devLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
|
||||
// wait for doPrefetchPromise
|
||||
await flushPromises()
|
||||
|
||||
expect(devLoader.apiRunner).toHaveBeenCalledTimes(2)
|
||||
expect(devLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
`onPrefetchPathname`,
|
||||
expect.anything()
|
||||
)
|
||||
expect(devLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
`onPostPrefetchPathname`,
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,59 +0,0 @@
|
|||
import "@babel/polyfill"
|
||||
const {
|
||||
reportError,
|
||||
clearError,
|
||||
errorMap,
|
||||
} = require(`../error-overlay-handler`)
|
||||
|
||||
import * as ErrorOverlay from "react-error-overlay"
|
||||
|
||||
jest.mock(`react-error-overlay`, () => {
|
||||
return {
|
||||
reportBuildError: jest.fn(),
|
||||
dismissBuildError: jest.fn(),
|
||||
startReportingRuntimeErrors: jest.fn(),
|
||||
setEditorHandler: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
ErrorOverlay.reportBuildError.mockClear()
|
||||
ErrorOverlay.dismissBuildError.mockClear()
|
||||
})
|
||||
|
||||
describe(`errorOverlayHandler`, () => {
|
||||
describe(`clearError()`, () => {
|
||||
beforeEach(() => {
|
||||
reportError(`foo`, `error`)
|
||||
reportError(`bar`, `error`)
|
||||
})
|
||||
afterAll(() => {
|
||||
clearError(`foo`)
|
||||
clearError(`bar`)
|
||||
})
|
||||
it(`should clear specific error type`, () => {
|
||||
expect(Object.keys(errorMap)).toHaveLength(2)
|
||||
clearError(`foo`)
|
||||
expect(Object.keys(errorMap)).toHaveLength(1)
|
||||
expect(ErrorOverlay.dismissBuildError).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it(`should call ErrorOverlay to dismiss build errors`, () => {
|
||||
clearError(`foo`)
|
||||
clearError(`bar`)
|
||||
expect(ErrorOverlay.dismissBuildError).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
describe(`reportErrorOverlay()`, () => {
|
||||
it(`should not add error if it's empty and not call ErrorOverlay`, () => {
|
||||
reportError(`foo`, null)
|
||||
expect(Object.keys(errorMap)).toHaveLength(0)
|
||||
expect(ErrorOverlay.reportBuildError).not.toHaveBeenCalled()
|
||||
})
|
||||
it(`should add error if it has a truthy value and call ErrorOverlay`, () => {
|
||||
reportError(`foo`, `bar`)
|
||||
expect(Object.keys(errorMap)).toHaveLength(1)
|
||||
expect(ErrorOverlay.reportBuildError).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,109 +0,0 @@
|
|||
import { cleanPath, setMatchPaths, findMatchPath, findPath } from "../find-path"
|
||||
|
||||
describe(`find-path`, () => {
|
||||
describe(`cleanPath`, () => {
|
||||
beforeEach(() => {
|
||||
global.__BASE_PATH__ = ``
|
||||
})
|
||||
|
||||
it(`should strip out ? & # from a pathname`, () => {
|
||||
expect(cleanPath(`/mypath#anchor?gatsby=cool`)).toBe(`/mypath`)
|
||||
})
|
||||
|
||||
it(`should convert a /index.html to root dir`, () => {
|
||||
expect(cleanPath(`/index.html`)).toBe(`/`)
|
||||
})
|
||||
|
||||
it(`strip out a basePrefix`, () => {
|
||||
global.__BASE_PATH__ = `/blog`
|
||||
expect(cleanPath(`/blog/mypath`)).toBe(`/mypath`)
|
||||
})
|
||||
})
|
||||
|
||||
describe(`findMatchPath`, () => {
|
||||
beforeEach(() => {
|
||||
// reset matchPaths
|
||||
setMatchPaths([])
|
||||
global.__BASE_PATH__ = ``
|
||||
})
|
||||
|
||||
it(`should find a path when matchPath found`, () => {
|
||||
setMatchPaths([
|
||||
{
|
||||
matchPath: `/app/*`,
|
||||
path: `/app`,
|
||||
},
|
||||
])
|
||||
|
||||
expect(findMatchPath(`/app/dynamic-page#anchor?gatsby=cool`)).toBe(`/app`)
|
||||
})
|
||||
|
||||
it(`should return null when no matchPathFound`, () => {
|
||||
setMatchPaths([
|
||||
{
|
||||
matchPath: `/app/*`,
|
||||
path: `/app`,
|
||||
},
|
||||
])
|
||||
|
||||
expect(findMatchPath(`/notanapp/dynamic-page`)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe(`findPath`, () => {
|
||||
beforeEach(() => {
|
||||
// reset matchPaths
|
||||
setMatchPaths([])
|
||||
global.__BASE_PATH__ = ``
|
||||
})
|
||||
|
||||
it(`should use matchPath if found`, () => {
|
||||
setMatchPaths([
|
||||
{
|
||||
matchPath: `/app/*`,
|
||||
path: `/app`,
|
||||
},
|
||||
])
|
||||
|
||||
expect(findPath(`/app/dynamic-page#anchor?gatsby=cool`)).toBe(`/app`)
|
||||
})
|
||||
|
||||
it(`should return the cleaned up path when no matchPathFound`, () => {
|
||||
setMatchPaths([
|
||||
{
|
||||
matchPath: `/app/*`,
|
||||
path: `/app`,
|
||||
},
|
||||
])
|
||||
|
||||
expect(findPath(`/notanapp/my-page#anchor?gatsby=cool`)).toBe(
|
||||
`/notanapp/my-page`
|
||||
)
|
||||
})
|
||||
|
||||
it(`should only process a request once`, () => {
|
||||
jest.resetModules()
|
||||
jest.mock(`@reach/router/lib/utils`)
|
||||
const findPath = require(`../find-path`).findPath
|
||||
const setMatchPaths = require(`../find-path`).setMatchPaths
|
||||
const match = require(`@reach/router/lib/utils`).match
|
||||
|
||||
setMatchPaths([
|
||||
{
|
||||
matchPath: `/app/*`,
|
||||
path: `/app`,
|
||||
},
|
||||
])
|
||||
|
||||
expect(findPath(`/notanapp/my-page#anchor?gatsby=cool`)).toBe(
|
||||
`/notanapp/my-page`
|
||||
)
|
||||
expect(findPath(`/notanapp/my-page#anchor?gatsby=cool`)).toBe(
|
||||
`/notanapp/my-page`
|
||||
)
|
||||
expect(findPath(`/notanapp/my-page`)).toBe(`/notanapp/my-page`)
|
||||
|
||||
expect(match).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,554 +0,0 @@
|
|||
// This is by no means a full test file for loader.js so feel free to add more tests.
|
||||
import mock from "xhr-mock"
|
||||
import { ProdLoader } from "../loader"
|
||||
import emitter from "../emitter"
|
||||
|
||||
jest.mock(`../emitter`)
|
||||
|
||||
describe(`Production loader`, () => {
|
||||
describe(`loadPageDataJson`, () => {
|
||||
let originalBasePath
|
||||
let originalPathPrefix
|
||||
let xhrCount
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @param {number} status
|
||||
* @param {string|Object?} responseText
|
||||
* @param {boolean?} json
|
||||
*/
|
||||
const mockPageData = (path, status, responseText = ``, json = false) => {
|
||||
mock.get(`/page-data${path}/page-data.json`, (req, res) => {
|
||||
xhrCount++
|
||||
if (json) {
|
||||
res.header(`content-type`, `application/json`)
|
||||
}
|
||||
|
||||
return res
|
||||
.status(status)
|
||||
.body(
|
||||
typeof responseText === `string`
|
||||
? responseText
|
||||
: JSON.stringify(responseText)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const defaultPayload = {
|
||||
path: `/mypage/`,
|
||||
}
|
||||
|
||||
// replace the real XHR object with the mock XHR object before each test
|
||||
beforeEach(() => {
|
||||
originalBasePath = global.__BASE_PATH__
|
||||
originalPathPrefix = global.__PATH_PREFIX__
|
||||
global.__BASE_PATH__ = ``
|
||||
global.__PATH_PREFIX__ = ``
|
||||
xhrCount = 0
|
||||
mock.setup()
|
||||
})
|
||||
|
||||
// put the real XHR object back and clear the mocks after each test
|
||||
afterEach(() => {
|
||||
global.__BASE_PATH__ = originalBasePath
|
||||
global.__PATH_PREFIX__ = originalPathPrefix
|
||||
mock.teardown()
|
||||
})
|
||||
|
||||
it(`should return a pageData json on success`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload: defaultPayload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(prodLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should return a pageData json on success without contentType`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload: defaultPayload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(prodLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should return a pageData json with an empty compilation hash (gatsby develop)`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, webpackCompilationHash: `` }
|
||||
mockPageData(`/mypage`, 200, payload)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/mypage`,
|
||||
payload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/mypage/`)).toEqual(expectation)
|
||||
expect(prodLoader.pageDataDb.get(`/mypage`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when page-path file is not a gatsby json`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200, { random: `string` }, true)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when page-path file is not a json`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should load a 404 page when path returns a 404`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
const payload = { ...defaultPayload, path: `/404.html/` }
|
||||
mockPageData(`/unknown-page`, 200)
|
||||
mockPageData(`/404.html`, 200, payload, true)
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
payload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should return a failure when status is 404 and 404 page is fetched`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/unknown-page`, 404)
|
||||
mockPageData(`/404.html`, 404)
|
||||
|
||||
const expectation = {
|
||||
status: `failure`,
|
||||
pagePath: `/404.html`,
|
||||
notFound: true,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/unknown-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/unknown-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`should return an error when status is 500`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/error-page`, 500)
|
||||
|
||||
const expectation = {
|
||||
status: `error`,
|
||||
pagePath: `/error-page`,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/error-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/error-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
|
||||
it(`should retry 3 times before returning an error`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/blocked-page`, 0)
|
||||
|
||||
const expectation = {
|
||||
status: `error`,
|
||||
retries: 3,
|
||||
pagePath: `/blocked-page`,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/blocked-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/blocked-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(4)
|
||||
})
|
||||
|
||||
it(`should recover if we get 1 failure`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
const payload = {
|
||||
path: `/blocked-page/`,
|
||||
}
|
||||
|
||||
let xhrCount = 0
|
||||
mock.get(`/page-data/blocked-page/page-data.json`, (req, res) => {
|
||||
if (xhrCount++ === 0) {
|
||||
return res.status(0).body(``)
|
||||
} else {
|
||||
res.header(`content-type`, `application/json`)
|
||||
return res.status(200).body(JSON.stringify(payload))
|
||||
}
|
||||
})
|
||||
|
||||
const expectation = {
|
||||
status: `success`,
|
||||
retries: 1,
|
||||
pagePath: `/blocked-page`,
|
||||
payload,
|
||||
}
|
||||
expect(await prodLoader.loadPageDataJson(`/blocked-page/`)).toEqual(
|
||||
expectation
|
||||
)
|
||||
expect(prodLoader.pageDataDb.get(`/blocked-page`)).toEqual(expectation)
|
||||
expect(xhrCount).toBe(2)
|
||||
})
|
||||
|
||||
it(`shouldn't load pageData multiple times`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
mockPageData(`/mypage`, 200, defaultPayload, true)
|
||||
|
||||
const expectation = await prodLoader.loadPageDataJson(`/mypage/`)
|
||||
expect(await prodLoader.loadPageDataJson(`/mypage/`)).toBe(expectation)
|
||||
expect(xhrCount).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe(`loadPage`, () => {
|
||||
const createAsyncRequires = components => {
|
||||
return {
|
||||
components,
|
||||
}
|
||||
}
|
||||
|
||||
let originalPathPrefix
|
||||
|
||||
beforeEach(() => {
|
||||
originalPathPrefix = global.__PATH_PREFIX__
|
||||
global.__PATH_PREFIX__ = ``
|
||||
mock.setup()
|
||||
mock.get(`/page-data/app-data.json`, (req, res) =>
|
||||
res
|
||||
.status(200)
|
||||
.header(`content-type`, `application/json`)
|
||||
.body(
|
||||
JSON.stringify({
|
||||
webpackCompilationHash: `123`,
|
||||
})
|
||||
)
|
||||
)
|
||||
emitter.emit.mockReset()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
global.__PATH_PREFIX__ = originalPathPrefix
|
||||
mock.teardown()
|
||||
})
|
||||
|
||||
it(`should be successful when component can be loaded`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(`instance`),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
result: {
|
||||
pageContext: `something something`,
|
||||
},
|
||||
}
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
const expectation = await prodLoader.loadPage(`/mypage/`)
|
||||
expect(expectation).toMatchSnapshot()
|
||||
expect(Object.keys(expectation)).toEqual([`component`, `json`, `page`])
|
||||
expect(prodLoader.pageDb.get(`/mypage`)).toEqual(
|
||||
expect.objectContaining({
|
||||
payload: expectation,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(1)
|
||||
expect(emitter.emit).toHaveBeenCalledWith(`onPostLoadPageResources`, {
|
||||
page: expectation,
|
||||
pageResources: expectation,
|
||||
})
|
||||
})
|
||||
|
||||
it(`should set not found on finalResult`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(`instance`),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
notFound: true,
|
||||
})
|
||||
)
|
||||
|
||||
await prodLoader.loadPage(`/mypage/`)
|
||||
const expectation = prodLoader.pageDb.get(`/mypage`)
|
||||
expect(expectation).toHaveProperty(`notFound`, true)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(1)
|
||||
expect(emitter.emit).toHaveBeenCalledWith(`onPostLoadPageResources`, {
|
||||
page: expectation.payload,
|
||||
pageResources: expectation.payload,
|
||||
})
|
||||
})
|
||||
|
||||
it(`should return an error when component cannot be loaded`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(false),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
await prodLoader.loadPage(`/mypage/`)
|
||||
const expectation = prodLoader.pageDb.get(`/mypage`)
|
||||
expect(expectation).toHaveProperty(`status`, `error`)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should return an error pageData contains an error`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(`instance`),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
const pageData = {
|
||||
path: `/mypage/`,
|
||||
componentChunkName: `chunk`,
|
||||
}
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: pageData,
|
||||
status: `error`,
|
||||
})
|
||||
)
|
||||
|
||||
expect(await prodLoader.loadPage(`/mypage/`)).toEqual({ status: `error` })
|
||||
expect(prodLoader.pageDb.size).toBe(0)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should throw an error when 404 cannot be fetched`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
status: `failure`,
|
||||
})
|
||||
)
|
||||
|
||||
try {
|
||||
await prodLoader.loadPage(`/404.html/`)
|
||||
} catch (err) {
|
||||
expect(err.message).toEqual(
|
||||
expect.stringContaining(`404 page could not be found`)
|
||||
)
|
||||
}
|
||||
expect(prodLoader.pageDb.size).toBe(0)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(0)
|
||||
})
|
||||
|
||||
it(`should cache the result of loadPage`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(`instance`),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: {
|
||||
componentChunkName: `chunk`,
|
||||
},
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
const expectation = await prodLoader.loadPage(`/mypage/`)
|
||||
expect(await prodLoader.loadPage(`/mypage/`)).toBe(expectation)
|
||||
expect(prodLoader.loadPageDataJson).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it(`should only run 1 network request even when called multiple times`, async () => {
|
||||
const asyncRequires = createAsyncRequires({
|
||||
chunk: () => Promise.resolve(`instance`),
|
||||
})
|
||||
const prodLoader = new ProdLoader(asyncRequires, [])
|
||||
prodLoader.loadPageDataJson = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
payload: {
|
||||
componentChunkName: `chunk`,
|
||||
},
|
||||
status: `success`,
|
||||
})
|
||||
)
|
||||
|
||||
const loadPagePromise = prodLoader.loadPage(`/test-page/`)
|
||||
expect(prodLoader.inFlightDb.size).toBe(1)
|
||||
expect(prodLoader.loadPage(`/test-page/`)).toBe(loadPagePromise)
|
||||
expect(prodLoader.inFlightDb.size).toBe(1)
|
||||
|
||||
const expectation = await loadPagePromise
|
||||
|
||||
expect(prodLoader.inFlightDb.size).toBe(0)
|
||||
expect(emitter.emit).toHaveBeenCalledTimes(1)
|
||||
expect(emitter.emit).toHaveBeenCalledWith(`onPostLoadPageResources`, {
|
||||
page: expectation,
|
||||
pageResources: expectation,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`loadPageSync`, () => {
|
||||
it(`returns page resources when already fetched`, () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
prodLoader.pageDb.set(`/mypage`, { payload: true })
|
||||
expect(prodLoader.loadPageSync(`/mypage/`)).toBe(true)
|
||||
})
|
||||
|
||||
it(`returns page resources when already fetched`, () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
|
||||
expect(prodLoader.loadPageSync(`/mypage/`)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe(`prefetch`, () => {
|
||||
const flushPromises = () => new Promise(resolve => setImmediate(resolve))
|
||||
|
||||
it(`shouldn't prefetch when shouldPrefetch is false`, () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
prodLoader.shouldPrefetch = jest.fn(() => false)
|
||||
prodLoader.doPrefetch = jest.fn()
|
||||
prodLoader.apiRunner = jest.fn()
|
||||
|
||||
expect(prodLoader.prefetch(`/mypath/`)).toBe(false)
|
||||
expect(prodLoader.shouldPrefetch).toHaveBeenCalledWith(`/mypath/`)
|
||||
expect(prodLoader.apiRunner).not.toHaveBeenCalled()
|
||||
expect(prodLoader.doPrefetch).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it(`should trigger custom prefetch logic when core is disabled`, () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
prodLoader.shouldPrefetch = jest.fn(() => true)
|
||||
prodLoader.doPrefetch = jest.fn()
|
||||
prodLoader.apiRunner = jest.fn()
|
||||
prodLoader.prefetchDisabled = true
|
||||
|
||||
expect(prodLoader.prefetch(`/mypath/`)).toBe(false)
|
||||
expect(prodLoader.shouldPrefetch).toHaveBeenCalledWith(`/mypath/`)
|
||||
expect(prodLoader.apiRunner).toHaveBeenCalledWith(`onPrefetchPathname`, {
|
||||
pathname: `/mypath/`,
|
||||
})
|
||||
expect(prodLoader.doPrefetch).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it(`should prefetch when not yet triggered`, async () => {
|
||||
jest.useFakeTimers()
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
prodLoader.shouldPrefetch = jest.fn(() => true)
|
||||
prodLoader.apiRunner = jest.fn()
|
||||
prodLoader.doPrefetch = jest.fn(() => Promise.resolve({}))
|
||||
|
||||
expect(prodLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
|
||||
// wait for doPrefetchPromise
|
||||
await flushPromises()
|
||||
|
||||
expect(prodLoader.apiRunner).toHaveBeenCalledWith(`onPrefetchPathname`, {
|
||||
pathname: `/mypath/`,
|
||||
})
|
||||
expect(prodLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
`onPostPrefetchPathname`,
|
||||
{
|
||||
pathname: `/mypath/`,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it(`should only run apis once`, async () => {
|
||||
const prodLoader = new ProdLoader(null, [])
|
||||
prodLoader.shouldPrefetch = jest.fn(() => true)
|
||||
prodLoader.apiRunner = jest.fn()
|
||||
prodLoader.doPrefetch = jest.fn(() => Promise.resolve({}))
|
||||
|
||||
expect(prodLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
expect(prodLoader.prefetch(`/mypath/`)).toBe(true)
|
||||
|
||||
// wait for doPrefetchPromise
|
||||
await flushPromises()
|
||||
|
||||
expect(prodLoader.apiRunner).toHaveBeenCalledTimes(2)
|
||||
expect(prodLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
`onPrefetchPathname`,
|
||||
expect.anything()
|
||||
)
|
||||
expect(prodLoader.apiRunner).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
`onPostPrefetchPathname`,
|
||||
expect.anything()
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,32 +0,0 @@
|
|||
const path = require(`path`)
|
||||
const child = require(`child_process`)
|
||||
|
||||
it(`Builds cache-dir with minimal config`, done => {
|
||||
const args = [
|
||||
require.resolve(`@babel/cli/bin/babel.js`),
|
||||
path.join(__dirname, `..`),
|
||||
`--config-file`,
|
||||
path.join(__dirname, `.babelrc`),
|
||||
`--ignore`,
|
||||
`**/__tests__`,
|
||||
]
|
||||
|
||||
const spawn = child.spawn(process.execPath, args)
|
||||
|
||||
let stderr = ``
|
||||
let stdout = ``
|
||||
|
||||
spawn.stderr.on(`data`, function(chunk) {
|
||||
stderr += chunk
|
||||
})
|
||||
|
||||
spawn.stdout.on(`data`, function(chunk) {
|
||||
stdout += chunk
|
||||
})
|
||||
|
||||
spawn.on(`close`, function() {
|
||||
expect(stderr).toEqual(``)
|
||||
expect(stdout).not.toEqual(``)
|
||||
done()
|
||||
})
|
||||
}, 30000)
|
|
@ -1,330 +0,0 @@
|
|||
import React from "react"
|
||||
import fs from "fs"
|
||||
const { join } = require(`path`)
|
||||
|
||||
import DevelopStaticEntry from "../develop-static-entry"
|
||||
|
||||
jest.mock(`fs`, () => {
|
||||
const fs = jest.requireActual(`fs`)
|
||||
return {
|
||||
...fs,
|
||||
readFileSync: jest.fn(),
|
||||
}
|
||||
})
|
||||
jest.mock(`gatsby/package.json`, () => {
|
||||
return {
|
||||
version: `2.0.0`,
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock(
|
||||
`../sync-requires`,
|
||||
() => {
|
||||
return {
|
||||
components: {
|
||||
"page-component---src-pages-test-js": () => null,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
virtual: true,
|
||||
}
|
||||
)
|
||||
|
||||
const MOCK_FILE_INFO = {
|
||||
[`${process.cwd()}/public/webpack.stats.json`]: `{}`,
|
||||
[`${process.cwd()}/public/chunk-map.json`]: `{}`,
|
||||
[join(
|
||||
process.cwd(),
|
||||
`/public/page-data/about/page-data.json`
|
||||
)]: JSON.stringify({
|
||||
componentChunkName: `page-component---src-pages-test-js`,
|
||||
path: `/about/`,
|
||||
webpackCompilationHash: `1234567890abcdef1234`,
|
||||
}),
|
||||
}
|
||||
|
||||
let StaticEntry
|
||||
beforeEach(() => {
|
||||
fs.readFileSync.mockImplementation(file => MOCK_FILE_INFO[file])
|
||||
StaticEntry = require(`../static-entry`).default
|
||||
})
|
||||
|
||||
const reverseHeadersPlugin = {
|
||||
plugin: {
|
||||
onPreRenderHTML: ({ getHeadComponents, replaceHeadComponents }) => {
|
||||
const headComponents = getHeadComponents()
|
||||
headComponents.reverse()
|
||||
replaceHeadComponents(headComponents)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const injectValuePlugin = (hookName, methodName, value) => {
|
||||
return {
|
||||
plugin: {
|
||||
[hookName]: staticEntry => {
|
||||
const method = staticEntry[methodName]
|
||||
method(value)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const checkSanitized = components => {
|
||||
expect(components.includes(null)).toBeFalsy()
|
||||
expect(
|
||||
components.find(val => Array.isArray(val) && val.length === 0)
|
||||
).toBeFalsy()
|
||||
expect(components.find(val => Array.isArray(val))).toBeFalsy()
|
||||
}
|
||||
|
||||
const checkNonEmptyHeadersPlugin = {
|
||||
plugin: {
|
||||
onPreRenderHTML: ({
|
||||
getHeadComponents,
|
||||
getPreBodyComponents,
|
||||
getPostBodyComponents,
|
||||
}) => {
|
||||
const headComponents = getHeadComponents()
|
||||
const preBodyComponents = getPreBodyComponents()
|
||||
const postBodyComponents = getPostBodyComponents()
|
||||
checkSanitized(headComponents)
|
||||
checkSanitized(preBodyComponents)
|
||||
checkSanitized(postBodyComponents)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const fakeStylesPlugin = {
|
||||
plugin: {
|
||||
onRenderBody: ({ setHeadComponents }) =>
|
||||
setHeadComponents([
|
||||
<style key="style1"> .style1 {} </style>,
|
||||
<style key="style2"> .style2 {} </style>,
|
||||
<style key="style3"> .style3 {} </style>,
|
||||
]),
|
||||
},
|
||||
}
|
||||
|
||||
const reverseBodyComponentsPluginFactory = type => {
|
||||
return {
|
||||
plugin: {
|
||||
onPreRenderHTML: props => {
|
||||
const components = props[`get${type}BodyComponents`]()
|
||||
components.reverse()
|
||||
props[`replace${type}BodyComponents`](components)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const fakeComponentsPluginFactory = type => {
|
||||
return {
|
||||
plugin: {
|
||||
onRenderBody: props => {
|
||||
props[`set${type}BodyComponents`]([
|
||||
<div key="div1"> div1 </div>,
|
||||
<div key="div2"> div2 </div>,
|
||||
<div key="div3"> div3 </div>,
|
||||
])
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
describe(`develop-static-entry`, () => {
|
||||
test(`onPreRenderHTML can be used to replace headComponents`, done => {
|
||||
global.plugins = [fakeStylesPlugin, reverseHeadersPlugin]
|
||||
|
||||
DevelopStaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML can be used to replace postBodyComponents`, done => {
|
||||
global.plugins = [
|
||||
fakeComponentsPluginFactory(`Post`),
|
||||
reverseBodyComponentsPluginFactory(`Post`),
|
||||
]
|
||||
|
||||
DevelopStaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML can be used to replace preBodyComponents`, done => {
|
||||
global.plugins = [
|
||||
fakeComponentsPluginFactory(`Pre`),
|
||||
reverseBodyComponentsPluginFactory(`Pre`),
|
||||
]
|
||||
|
||||
DevelopStaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML adds metatag note for development environment`, done => {
|
||||
DevelopStaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toContain(
|
||||
`<meta name="note" content="environment=development"/>`
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML adds metatag note for development environment after replaceHeadComponents`, done => {
|
||||
global.plugins = [reverseHeadersPlugin]
|
||||
|
||||
DevelopStaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toContain(
|
||||
`<meta name="note" content="environment=development"/>`
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`static-entry sanity checks`, () => {
|
||||
beforeEach(() => {
|
||||
global.__PATH_PREFIX__ = ``
|
||||
global.__BASE_PATH__ = ``
|
||||
global.__ASSET_PREFIX__ = ``
|
||||
})
|
||||
|
||||
const methodsToCheck = [
|
||||
`replaceHeadComponents`,
|
||||
`replacePreBodyComponents`,
|
||||
`replacePostBodyComponents`,
|
||||
]
|
||||
|
||||
methodsToCheck.forEach(methodName => {
|
||||
test(`${methodName} can filter out null value`, done => {
|
||||
const plugin = injectValuePlugin(`onPreRenderHTML`, methodName, null)
|
||||
global.plugins = [plugin, checkNonEmptyHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`${methodName} can filter out null values`, done => {
|
||||
const plugin = injectValuePlugin(`onPreRenderHTML`, methodName, [
|
||||
null,
|
||||
null,
|
||||
])
|
||||
global.plugins = [plugin, checkNonEmptyHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`${methodName} can filter out empty array`, done => {
|
||||
const plugin = injectValuePlugin(`onPreRenderHTML`, methodName, [])
|
||||
global.plugins = [plugin, checkNonEmptyHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`${methodName} can filter out empty arrays`, done => {
|
||||
const plugin = injectValuePlugin(`onPreRenderHTML`, methodName, [[], []])
|
||||
global.plugins = [plugin, checkNonEmptyHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`${methodName} can flatten arrays`, done => {
|
||||
const plugin = injectValuePlugin(`onPreRenderHTML`, methodName, [
|
||||
<style key="style1"> .style1 {} </style>,
|
||||
<style key="style2"> .style2 {} </style>,
|
||||
<style key="style3"> .style3 {} </style>,
|
||||
[<style key="style4"> .style3 {} </style>],
|
||||
])
|
||||
global.plugins = [plugin, checkNonEmptyHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`static-entry`, () => {
|
||||
beforeEach(() => {
|
||||
global.__PATH_PREFIX__ = ``
|
||||
global.__BASE_PATH__ = ``
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML can be used to replace headComponents`, done => {
|
||||
global.plugins = [fakeStylesPlugin, reverseHeadersPlugin]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML can be used to replace postBodyComponents`, done => {
|
||||
global.plugins = [
|
||||
fakeComponentsPluginFactory(`Post`),
|
||||
reverseBodyComponentsPluginFactory(`Post`),
|
||||
]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML can be used to replace preBodyComponents`, done => {
|
||||
global.plugins = [
|
||||
fakeComponentsPluginFactory(`Pre`),
|
||||
reverseBodyComponentsPluginFactory(`Pre`),
|
||||
]
|
||||
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).toMatchSnapshot()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test(`onPreRenderHTML does not add metatag note for development environment`, done => {
|
||||
StaticEntry(`/about/`, (_, html) => {
|
||||
expect(html).not.toContain(
|
||||
`<meta name="note" content="environment=development"/>`
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe(`sanitizeComponents`, () => {
|
||||
let sanitizeComponents
|
||||
|
||||
beforeEach(() => {
|
||||
fs.readFileSync.mockImplementation(file => MOCK_FILE_INFO[file])
|
||||
sanitizeComponents = require(`../static-entry`).sanitizeComponents
|
||||
})
|
||||
|
||||
it(`strips assetPrefix for manifest link`, () => {
|
||||
global.__PATH_PREFIX__ = `https://gatsbyjs.org/blog`
|
||||
global.__BASE_PATH__ = `/blog`
|
||||
global.__ASSET_PREFIX__ = `https://gatsbyjs.org`
|
||||
|
||||
const sanitizedComponents = sanitizeComponents([
|
||||
<link
|
||||
rel="manifest"
|
||||
href="https://gatsbyjs.org/blog/manifest.webmanifest"
|
||||
/>,
|
||||
])
|
||||
expect(sanitizedComponents[0].props.href).toBe(`/blog/manifest.webmanifest`)
|
||||
})
|
||||
})
|
|
@ -1,27 +0,0 @@
|
|||
const stripPrefix = require(`../strip-prefix`).default
|
||||
|
||||
describe(`strip-prefix`, () => {
|
||||
it(`strips a prefix`, () => {
|
||||
expect(stripPrefix(`/foo/bar/`, `/foo`)).toBe(`/bar/`)
|
||||
})
|
||||
|
||||
it(`strips first instance only`, () => {
|
||||
expect(stripPrefix(`/foo/foo/bar/`, `/foo`)).toBe(`/foo/bar/`)
|
||||
})
|
||||
|
||||
it(`strips full instance only`, () => {
|
||||
expect(stripPrefix(`/footest/`, `/foo`)).toBe(`/footest/`)
|
||||
})
|
||||
|
||||
it(`ignores prefix appearing elsewhere in the string`, () => {
|
||||
expect(stripPrefix(`/foo/bar/`, `bar`)).toBe(`/foo/bar/`)
|
||||
})
|
||||
|
||||
it(`ignores a non-existent prefix`, () => {
|
||||
expect(stripPrefix(`/bar`, `/foo`)).toBe(`/bar`)
|
||||
})
|
||||
|
||||
it(`returns input str if no prefix is provided`, () => {
|
||||
expect(stripPrefix(`/bar`)).toBe(`/bar`)
|
||||
})
|
||||
})
|
|
@ -1,31 +0,0 @@
|
|||
module.exports = [{
|
||||
plugin: require('../node_modules/gatsby-remark-autolink-headers/gatsby-browser.js'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-offline/gatsby-browser.js'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-manifest/gatsby-browser.js'),
|
||||
options: {"plugins":[],"name":"gatsby-starter-default","short_name":"starter","start_url":"/","background_color":"#722ED1","theme_color":"#722ED1","display":"minimal-ui","icon":"/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@antv/gatsby-theme-antv/site/images/favicon.png"},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-catch-links/gatsby-browser.js'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-nprogress/gatsby-browser.js'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-layout/gatsby-browser.js'),
|
||||
options: {"plugins":[],"component":"/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@antv/gatsby-theme-antv/site/layouts/layout.tsx"},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-nprogress/gatsby-browser.js'),
|
||||
options: {"plugins":[],"color":"#722ED1"},
|
||||
},{
|
||||
plugin: require('../node_modules/gatsby-plugin-google-analytics/gatsby-browser.js'),
|
||||
options: {"plugins":[],"trackingId":"UA-148148901-7"},
|
||||
},{
|
||||
plugin: require('../node_modules/@antv/gatsby-theme-antv/gatsby-browser.js'),
|
||||
options: {"plugins":[],"GATrackingId":"UA-148148901-7"},
|
||||
},{
|
||||
plugin: require('../gatsby-browser.js'),
|
||||
options: {"plugins":[]},
|
||||
}]
|
|
@ -1,61 +0,0 @@
|
|||
const plugins = require(`./api-runner-browser-plugins`)
|
||||
const {
|
||||
getResourcesForPathname,
|
||||
getResourcesForPathnameSync,
|
||||
getResourceURLsForPathname,
|
||||
loadPage,
|
||||
loadPageSync,
|
||||
} = require(`./loader`).publicLoader
|
||||
|
||||
exports.apiRunner = (api, args = {}, defaultReturn, argTransform) => {
|
||||
// Hooks for gatsby-cypress's API handler
|
||||
if (process.env.CYPRESS_SUPPORT) {
|
||||
if (window.___apiHandler) {
|
||||
window.___apiHandler(api)
|
||||
} else if (window.___resolvedAPIs) {
|
||||
window.___resolvedAPIs.push(api)
|
||||
} else {
|
||||
window.___resolvedAPIs = [api]
|
||||
}
|
||||
}
|
||||
|
||||
let results = plugins.map(plugin => {
|
||||
if (!plugin.plugin[api]) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Deprecated April 2019. Use `loadPageSync` instead
|
||||
args.getResourcesForPathnameSync = getResourcesForPathnameSync
|
||||
// Deprecated April 2019. Use `loadPage` instead
|
||||
args.getResourcesForPathname = getResourcesForPathname
|
||||
args.getResourceURLsForPathname = getResourceURLsForPathname
|
||||
args.loadPage = loadPage
|
||||
args.loadPageSync = loadPageSync
|
||||
|
||||
const result = plugin.plugin[api](args, plugin.options)
|
||||
if (result && argTransform) {
|
||||
args = argTransform({ args, result, plugin })
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
// Filter out undefined results.
|
||||
results = results.filter(result => typeof result !== `undefined`)
|
||||
|
||||
if (results.length > 0) {
|
||||
return results
|
||||
} else if (defaultReturn) {
|
||||
return [defaultReturn]
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
exports.apiRunnerAsync = (api, args, defaultReturn) =>
|
||||
plugins.reduce(
|
||||
(previous, next) =>
|
||||
next.plugin[api]
|
||||
? previous.then(() => next.plugin[api](args, next.options))
|
||||
: previous,
|
||||
Promise.resolve()
|
||||
)
|
|
@ -1,67 +0,0 @@
|
|||
var plugins = [{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-react-helmet/gatsby-ssr'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-remark-autolink-headers/gatsby-ssr'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-offline/gatsby-ssr'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-manifest/gatsby-ssr'),
|
||||
options: {"plugins":[],"name":"gatsby-starter-default","short_name":"starter","start_url":"/","background_color":"#722ED1","theme_color":"#722ED1","display":"minimal-ui","icon":"/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@antv/gatsby-theme-antv/site/images/favicon.png"},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-sitemap/gatsby-ssr'),
|
||||
options: {"plugins":[]},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-layout/gatsby-ssr'),
|
||||
options: {"plugins":[],"component":"/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@antv/gatsby-theme-antv/site/layouts/layout.tsx"},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/gatsby-plugin-google-analytics/gatsby-ssr'),
|
||||
options: {"plugins":[],"trackingId":"UA-148148901-7"},
|
||||
},{
|
||||
plugin: require('/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@antv/gatsby-theme-antv/gatsby-ssr'),
|
||||
options: {"plugins":[],"GATrackingId":"UA-148148901-7"},
|
||||
}]
|
||||
// During bootstrap, we write requires at top of this file which looks like:
|
||||
// var plugins = [
|
||||
// {
|
||||
// plugin: require("/path/to/plugin1/gatsby-ssr.js"),
|
||||
// options: { ... },
|
||||
// },
|
||||
// {
|
||||
// plugin: require("/path/to/plugin2/gatsby-ssr.js"),
|
||||
// options: { ... },
|
||||
// },
|
||||
// ]
|
||||
|
||||
const apis = require(`./api-ssr-docs`)
|
||||
|
||||
// Run the specified API in any plugins that have implemented it
|
||||
module.exports = (api, args, defaultReturn, argTransform) => {
|
||||
if (!apis[api]) {
|
||||
console.log(`This API doesn't exist`, api)
|
||||
}
|
||||
|
||||
// Run each plugin in series.
|
||||
// eslint-disable-next-line no-undef
|
||||
let results = plugins.map(plugin => {
|
||||
if (!plugin.plugin[api]) {
|
||||
return undefined
|
||||
}
|
||||
const result = plugin.plugin[api](args, plugin.options)
|
||||
if (result && argTransform) {
|
||||
args = argTransform({ args, result })
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
// Filter out undefined results.
|
||||
results = results.filter(result => typeof result !== `undefined`)
|
||||
|
||||
if (results.length > 0) {
|
||||
return results
|
||||
} else {
|
||||
return [defaultReturn]
|
||||
}
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
/**
|
||||
* Object containing options defined in `gatsby-config.js`
|
||||
* @typedef {object} pluginOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replace the default server renderer. This is useful for integration with
|
||||
* Redux, css-in-js libraries, etc. that need custom setups for server
|
||||
* rendering.
|
||||
* @param {object} $0
|
||||
* @param {string} $0.pathname The pathname of the page currently being rendered.
|
||||
* @param {function} $0.replaceBodyHTMLString Call this with the HTML string
|
||||
* you render. **WARNING** if multiple plugins implement this API it's the
|
||||
* last plugin that "wins". TODO implement an automated warning against this.
|
||||
* @param {function} $0.setHeadComponents Takes an array of components as its
|
||||
* first argument which are added to the `headComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setHtmlAttributes Takes an object of props which will
|
||||
* spread into the `<html>` component.
|
||||
* @param {function} $0.setBodyAttributes Takes an object of props which will
|
||||
* spread into the `<body>` component.
|
||||
* @param {function} $0.setPreBodyComponents Takes an array of components as its
|
||||
* first argument which are added to the `preBodyComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setPostBodyComponents Takes an array of components as its
|
||||
* first argument which are added to the `postBodyComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setBodyProps Takes an object of data which
|
||||
* is merged with other body props and passed to `html.js` as `bodyProps`.
|
||||
* @param {pluginOptions} pluginOptions
|
||||
* @example
|
||||
* // From gatsby-plugin-glamor
|
||||
* const { renderToString } = require("react-dom/server")
|
||||
* const inline = require("glamor-inline")
|
||||
*
|
||||
* exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
|
||||
* const bodyHTML = renderToString(bodyComponent)
|
||||
* const inlinedHTML = inline(bodyHTML)
|
||||
*
|
||||
* replaceBodyHTMLString(inlinedHTML)
|
||||
* }
|
||||
*/
|
||||
exports.replaceRenderer = true
|
||||
|
||||
/**
|
||||
* Called after every page Gatsby server renders while building HTML so you can
|
||||
* set head and body components to be rendered in your `html.js`.
|
||||
*
|
||||
* Gatsby does a two-pass render for HTML. It loops through your pages first
|
||||
* rendering only the body and then takes the result body HTML string and
|
||||
* passes it as the `body` prop to your `html.js` to complete the render.
|
||||
*
|
||||
* It's often handy to be able to send custom components to your `html.js`.
|
||||
* For example, it's a very common pattern for React.js libraries that
|
||||
* support server rendering to pull out data generated during the render to
|
||||
* add to your HTML.
|
||||
*
|
||||
* Using this API over [`replaceRenderer`](#replaceRenderer) is preferable as
|
||||
* multiple plugins can implement this API where only one plugin can take
|
||||
* over server rendering. However, if your plugin requires taking over server
|
||||
* rendering then that's the one to
|
||||
* use
|
||||
* @param {object} $0
|
||||
* @param {string} $0.pathname The pathname of the page currently being rendered.
|
||||
* @param {function} $0.setHeadComponents Takes an array of components as its
|
||||
* first argument which are added to the `headComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setHtmlAttributes Takes an object of props which will
|
||||
* spread into the `<html>` component.
|
||||
* @param {function} $0.setBodyAttributes Takes an object of props which will
|
||||
* spread into the `<body>` component.
|
||||
* @param {function} $0.setPreBodyComponents Takes an array of components as its
|
||||
* first argument which are added to the `preBodyComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setPostBodyComponents Takes an array of components as its
|
||||
* first argument which are added to the `postBodyComponents` array which is passed
|
||||
* to the `html.js` component.
|
||||
* @param {function} $0.setBodyProps Takes an object of data which
|
||||
* is merged with other body props and passed to `html.js` as `bodyProps`.
|
||||
* @param {pluginOptions} pluginOptions
|
||||
* @example
|
||||
* const { Helmet } = require("react-helmet")
|
||||
*
|
||||
* exports.onRenderBody = (
|
||||
* { setHeadComponents, setHtmlAttributes, setBodyAttributes },
|
||||
* pluginOptions
|
||||
* ) => {
|
||||
* const helmet = Helmet.renderStatic()
|
||||
* setHtmlAttributes(helmet.htmlAttributes.toComponent())
|
||||
* setBodyAttributes(helmet.bodyAttributes.toComponent())
|
||||
* setHeadComponents([
|
||||
* helmet.title.toComponent(),
|
||||
* helmet.link.toComponent(),
|
||||
* helmet.meta.toComponent(),
|
||||
* helmet.noscript.toComponent(),
|
||||
* helmet.script.toComponent(),
|
||||
* helmet.style.toComponent(),
|
||||
* ])
|
||||
* }
|
||||
*/
|
||||
exports.onRenderBody = true
|
||||
|
||||
/**
|
||||
* Called after every page Gatsby server renders while building HTML so you can
|
||||
* replace head components to be rendered in your `html.js`. This is useful if
|
||||
* you need to reorder scripts or styles added by other plugins.
|
||||
* @param {object} $0
|
||||
* @param {string} $0.pathname The pathname of the page currently being rendered.
|
||||
* @param {Array<ReactNode>} $0.getHeadComponents Returns the current `headComponents` array.
|
||||
* @param {function} $0.replaceHeadComponents Takes an array of components as its
|
||||
* first argument which replace the `headComponents` array which is passed
|
||||
* to the `html.js` component. **WARNING** if multiple plugins implement this
|
||||
* API it's the last plugin that "wins".
|
||||
* @param {Array<ReactNode>} $0.getPreBodyComponents Returns the current `preBodyComponents` array.
|
||||
* @param {function} $0.replacePreBodyComponents Takes an array of components as its
|
||||
* first argument which replace the `preBodyComponents` array which is passed
|
||||
* to the `html.js` component. **WARNING** if multiple plugins implement this
|
||||
* API it's the last plugin that "wins".
|
||||
* @param {Array<ReactNode>} $0.getPostBodyComponents Returns the current `postBodyComponents` array.
|
||||
* @param {function} $0.replacePostBodyComponents Takes an array of components as its
|
||||
* first argument which replace the `postBodyComponents` array which is passed
|
||||
* to the `html.js` component. **WARNING** if multiple plugins implement this
|
||||
* API it's the last plugin that "wins".
|
||||
* @param {pluginOptions} pluginOptions
|
||||
* @example
|
||||
* // Move Typography.js styles to the top of the head section so they're loaded first.
|
||||
* exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {
|
||||
* const headComponents = getHeadComponents()
|
||||
* headComponents.sort((x, y) => {
|
||||
* if (x.key === 'TypographyStyle') {
|
||||
* return -1
|
||||
* } else if (y.key === 'TypographyStyle') {
|
||||
* return 1
|
||||
* }
|
||||
* return 0
|
||||
* })
|
||||
* replaceHeadComponents(headComponents)
|
||||
* }
|
||||
*/
|
||||
exports.onPreRenderHTML = true
|
||||
|
||||
/**
|
||||
* Allow a plugin to wrap the page element.
|
||||
*
|
||||
* This is useful for setting wrapper components around pages that won't get
|
||||
* unmounted on page changes. For setting Provider components, use [wrapRootElement](#wrapRootElement).
|
||||
*
|
||||
* _Note:_
|
||||
* There is an equivalent hook in Gatsby's [Browser API](/docs/browser-apis/#wrapPageElement).
|
||||
* It is recommended to use both APIs together.
|
||||
* For example usage, check out [Using i18n](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-i18n).
|
||||
* @param {object} $0
|
||||
* @param {ReactNode} $0.element The "Page" React Element built by Gatsby.
|
||||
* @param {object} $0.props Props object used by page.
|
||||
* @param {pluginOptions} pluginOptions
|
||||
* @returns {ReactNode} Wrapped element
|
||||
* @example
|
||||
* const React = require("react")
|
||||
* const Layout = require("./src/components/layout").default
|
||||
*
|
||||
* exports.wrapPageElement = ({ element, props }) => {
|
||||
* // props provide same data to Layout as Page element will get
|
||||
* // including location, data, etc - you don't need to pass it
|
||||
* return <Layout {...props}>{element}</Layout>
|
||||
* }
|
||||
*/
|
||||
exports.wrapPageElement = true
|
||||
|
||||
/**
|
||||
* Allow a plugin to wrap the root element.
|
||||
*
|
||||
* This is useful to set up any Provider components that will wrap your application.
|
||||
* For setting persistent UI elements around pages use [wrapPageElement](#wrapPageElement).
|
||||
*
|
||||
* _Note:_
|
||||
* There is an equivalent hook in Gatsby's [Browser API](/docs/browser-apis/#wrapRootElement).
|
||||
* It is recommended to use both APIs together.
|
||||
* For example usage, check out [Using redux](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-redux).
|
||||
* @param {object} $0
|
||||
* @param {ReactNode} $0.element The "Root" React Element built by Gatsby.
|
||||
* @param {pluginOptions} pluginOptions
|
||||
* @returns {ReactNode} Wrapped element
|
||||
* @example
|
||||
* const React = require("react")
|
||||
* const { Provider } = require("react-redux")
|
||||
*
|
||||
* const createStore = require("./src/state/createStore")
|
||||
* const store = createStore()
|
||||
*
|
||||
* exports.wrapRootElement = ({ element }) => {
|
||||
* return (
|
||||
* <Provider store={store}>
|
||||
* {element}
|
||||
* </Provider>
|
||||
* )
|
||||
* }
|
||||
*/
|
||||
exports.wrapRootElement = true
|
|
@ -1,72 +0,0 @@
|
|||
import React from "react"
|
||||
import ReactDOM from "react-dom"
|
||||
import domReady from "@mikaelkristiansson/domready"
|
||||
|
||||
import socketIo from "./socketIo"
|
||||
import emitter from "./emitter"
|
||||
import { apiRunner, apiRunnerAsync } from "./api-runner-browser"
|
||||
import { setLoader, publicLoader } from "./loader"
|
||||
import DevLoader from "./dev-loader"
|
||||
import syncRequires from "./sync-requires"
|
||||
// Generated during bootstrap
|
||||
import matchPaths from "./match-paths.json"
|
||||
|
||||
window.___emitter = emitter
|
||||
|
||||
const loader = new DevLoader(syncRequires, matchPaths)
|
||||
setLoader(loader)
|
||||
loader.setApiRunner(apiRunner)
|
||||
|
||||
window.___loader = publicLoader
|
||||
|
||||
// Let the site/plugins run code very early.
|
||||
apiRunnerAsync(`onClientEntry`).then(() => {
|
||||
// Hook up the client to socket.io on server
|
||||
const socket = socketIo()
|
||||
if (socket) {
|
||||
socket.on(`reload`, () => {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Service Workers are persistent by nature. They stick around,
|
||||
* serving a cached version of the site if they aren't removed.
|
||||
* This is especially frustrating when you need to test the
|
||||
* production build on your local machine.
|
||||
*
|
||||
* Let's warn if we find service workers in development.
|
||||
*/
|
||||
if (`serviceWorker` in navigator) {
|
||||
navigator.serviceWorker.getRegistrations().then(registrations => {
|
||||
if (registrations.length > 0)
|
||||
console.warn(
|
||||
`Warning: found one or more service workers present.`,
|
||||
`If your site isn't behaving as expected, you might want to remove these.`,
|
||||
registrations
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const rootElement = document.getElementById(`___gatsby`)
|
||||
|
||||
const renderer = apiRunner(
|
||||
`replaceHydrateFunction`,
|
||||
undefined,
|
||||
ReactDOM.render
|
||||
)[0]
|
||||
|
||||
Promise.all([
|
||||
loader.loadPage(`/dev-404-page/`),
|
||||
loader.loadPage(`/404.html`),
|
||||
loader.loadPage(window.location.pathname),
|
||||
]).then(() => {
|
||||
const preferDefault = m => (m && m.default) || m
|
||||
let Root = preferDefault(require(`./root`))
|
||||
domReady(() => {
|
||||
renderer(<Root />, rootElement, () => {
|
||||
apiRunner(`onInitialClientRender`)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,13 +0,0 @@
|
|||
// prefer default export if available
|
||||
const preferDefault = m => m && m.default || m
|
||||
|
||||
exports.components = {
|
||||
"component---node-modules-antv-gatsby-theme-antv-site-templates-document-tsx": () => import("../node_modules/@antv/gatsby-theme-antv/site/templates/document.tsx" /* webpackChunkName: "component---node-modules-antv-gatsby-theme-antv-site-templates-document-tsx" */),
|
||||
"component---node-modules-antv-gatsby-theme-antv-site-templates-example-tsx": () => import("../node_modules/@antv/gatsby-theme-antv/site/templates/example.tsx" /* webpackChunkName: "component---node-modules-antv-gatsby-theme-antv-site-templates-example-tsx" */),
|
||||
"component---cache-dev-404-page-js": () => import("dev-404-page.js" /* webpackChunkName: "component---cache-dev-404-page-js" */),
|
||||
"component---node-modules-antv-gatsby-theme-antv-site-pages-index-tsx": () => import("../node_modules/@antv/gatsby-theme-antv/site/pages/index.tsx" /* webpackChunkName: "component---node-modules-antv-gatsby-theme-antv-site-pages-index-tsx" */),
|
||||
"component---node-modules-antv-gatsby-theme-antv-site-pages-404-tsx": () => import("../node_modules/@antv/gatsby-theme-antv/site/pages/404.tsx" /* webpackChunkName: "component---node-modules-antv-gatsby-theme-antv-site-pages-404-tsx" */),
|
||||
"component---site-pages-index-en-tsx": () => import("../site/pages/index.en.tsx" /* webpackChunkName: "component---site-pages-index-en-tsx" */),
|
||||
"component---site-pages-index-zh-tsx": () => import("../site/pages/index.zh.tsx" /* webpackChunkName: "component---site-pages-index-zh-tsx" */)
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
{
|
||||
"stages": {
|
||||
"develop": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-numeric-separator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "babel-plugin-import",
|
||||
"options": {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/preset-typescript/lib/index.js",
|
||||
"options": {
|
||||
"plugins": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"cacheDirectory": true,
|
||||
"sourceType": "unambiguous"
|
||||
}
|
||||
},
|
||||
"develop-html": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-numeric-separator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "babel-plugin-import",
|
||||
"options": {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/preset-typescript/lib/index.js",
|
||||
"options": {
|
||||
"plugins": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"cacheDirectory": true,
|
||||
"sourceType": "unambiguous"
|
||||
}
|
||||
},
|
||||
"build-html": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-numeric-separator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "babel-plugin-import",
|
||||
"options": {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/preset-typescript/lib/index.js",
|
||||
"options": {
|
||||
"plugins": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"cacheDirectory": true,
|
||||
"sourceType": "unambiguous"
|
||||
}
|
||||
},
|
||||
"build-javascript": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/plugin-proposal-numeric-separator/lib/index.js",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "babel-plugin-import",
|
||||
"options": {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"name": "/Users/lizhengxue/Documents/AntV/github/L7_2.0/L7/node_modules/@babel/preset-typescript/lib/index.js",
|
||||
"options": {
|
||||
"plugins": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
"cacheDirectory": true,
|
||||
"sourceType": "unambiguous"
|
||||
}
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
">0.25%",
|
||||
"not dead"
|
||||
]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-ad3a0411bb469460edbd1820d1a953f5-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-22e40979220b547ee56864978d7eefed-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<p>指需要用一连串首尾闭合相等数值点的连线的图层,表示连续分布且逐渐变化的数量特征的地图,常用于等高线图、等温线图等图。</p>"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-2b56a382712fe8167708fc9c6567ee2a-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/en/docs/api/component/marker/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/en/docs/api/component/marker/#option\">option</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/component/marker/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/en/docs/api/component/marker/#setlnglat\">setLnglat</a></li>\n<li><a href=\"/en/docs/api/component/marker/#addto\">addTo</a></li>\n<li><a href=\"/en/docs/api/component/marker/#remove\">remove</a></li>\n<li><a href=\"/en/docs/api/component/marker/#getelement\">getElement</a></li>\n<li><a href=\"/en/docs/api/component/marker/#getlnglat\">getLngLat</a></li>\n<li><a href=\"/en/docs/api/component/marker/#togglepopup\">togglePopup</a></li>\n<li><a href=\"/en/docs/api/component/marker/#setpopup\">setPopup</a></li>\n<li><a href=\"/en/docs/api/component/marker/#getpopup\">getPopup</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/component/marker/#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81\">示例代码</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/en/docs/api/component/marker/#%E9%BB%98%E8%AE%A4marker\">默认Marker</a></li>\n<li><a href=\"/en/docs/api/component/marker/#%E8%87%AA%E5%AE%9A%E4%B9%89marker\">自定义Marker</a></li>\n<li><a href=\"/en/docs/api/component/marker/#%E8%AE%BE%E7%BD%AE-popup\">设置 popup</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-b547ac3a0b516aef90927b09bdc0a22c-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/component/popup/#popup\">popup</a></p>\n<ul>\n<li>\n<p><a href=\"/zh/docs/api/component/popup/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/popup/#option\">option</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/popup/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/popup/#setlnglat\">setLnglat</a></li>\n<li><a href=\"/zh/docs/api/component/popup/#addto\">addTo</a></li>\n<li><a href=\"/zh/docs/api/component/popup/#sethtml\">setHtml</a></li>\n<li><a href=\"/zh/docs/api/component/popup/#settext\">setText</a></li>\n<li><a href=\"/zh/docs/api/component/popup/#remove\">remove</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/popup/#%E4%BA%8B%E4%BB%B6\">事件</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/popup/#close\">close</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/popup/#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81\">示例代码</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/popup/#%E6%B7%BB%E5%8A%A0popup\">添加popup</a></li>\n</ul>\n</li>\n<li><a href=\"/zh/docs/api/component/popup/#faq\">FAQ</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-3fdafdf445bd057a86b5717b80c92ebf-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/en/docs/api/scene/#%E7%AE%80%E4%BB%8B\">简介</a></p>\n<ul>\n<li><a href=\"/en/docs/api/scene/#scene\">Scene</a></li>\n<li>\n<p><a href=\"/en/docs/api/scene/#map\">Map</a></p>\n<ul>\n<li><a href=\"/en/docs/api/scene/#map-1\">map</a></li>\n<li><a href=\"/en/docs/api/scene/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/scene/#%E9%85%8D%E7%BD%AE%E9%A1%B9\">配置项</a></p>\n<ul>\n<li><a href=\"/en/docs/api/scene/#%E5%9C%B0%E5%9B%BE%E9%85%8D%E7%BD%AE%E9%A1%B9\">地图配置项</a></li>\n<li><a href=\"/en/docs/api/scene/#id\">id</a></li>\n<li><a href=\"/en/docs/api/scene/#zoom\">zoom</a></li>\n<li><a href=\"/en/docs/api/scene/#center\">center</a></li>\n<li><a href=\"/en/docs/api/scene/#pitch\">pitch</a></li>\n<li><a href=\"/en/docs/api/scene/#style\">style</a></li>\n<li><a href=\"/en/docs/api/scene/#minzoom\">minZoom</a></li>\n<li><a href=\"/en/docs/api/scene/#maxzoom\">maxZoom</a></li>\n<li><a href=\"/en/docs/api/scene/#rotateenable\">rotateEnable</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/scene/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li><a href=\"/en/docs/api/scene/#getzoom\">getZoom</a></li>\n<li><a href=\"/en/docs/api/scene/#getlayers\">getLayers()</a></li>\n<li><a href=\"/en/docs/api/scene/#getcenter\">getCenter()</a></li>\n<li><a href=\"/en/docs/api/scene/#getsize\">getSize()</a></li>\n<li><a href=\"/en/docs/api/scene/#getpitch\">getPitch()</a></li>\n<li><a href=\"/en/docs/api/scene/#setcenter\">setCenter()</a></li>\n<li><a href=\"/en/docs/api/scene/#setzoomandcenter\">setZoomAndCenter</a></li>\n<li><a href=\"/en/docs/api/scene/#setrotation\">setRotation</a></li>\n<li><a href=\"/en/docs/api/scene/#zoomin\">zoomIn</a></li>\n<li><a href=\"/en/docs/api/scene/#zoomout\">zoomOut</a></li>\n<li><a href=\"/en/docs/api/scene/#panto\">panTo</a></li>\n<li><a href=\"/en/docs/api/scene/#panby\">panBy</a></li>\n<li><a href=\"/en/docs/api/scene/#setpitch\">setPitch</a></li>\n<li><a href=\"/en/docs/api/scene/#fitbounds\">fitBounds</a></li>\n<li><a href=\"/en/docs/api/scene/#removelayer\">removeLayer</a></li>\n<li><a href=\"/en/docs/api/scene/#getlayers-1\">getLayers</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/scene/#%E4%BA%8B%E4%BB%B6\">事件</a></p>\n<ul>\n<li>\n<p><a href=\"/en/docs/api/scene/#on\">on</a></p>\n<ul>\n<li><a href=\"/en/docs/api/scene/#%E5%8F%82%E6%95%B0\">参数</a></li>\n</ul>\n</li>\n<li><a href=\"/en/docs/api/scene/#off\">off</a></li>\n<li><a href=\"/en/docs/api/scene/#%E5%9C%B0%E5%9B%BE%E4%BA%8B%E4%BB%B6\">地图事件</a></li>\n<li><a href=\"/en/docs/api/scene/#%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6\">鼠标事件</a></li>\n<li><a href=\"/en/docs/api/scene/#%E5%85%B6%E5%AE%83%E4%BA%8B%E4%BB%B6\">其它事件</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-41aa0a12479519ad49d76176cb6f7dd9-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<h1 id=\"填充图\"><a href=\"#%E5%A1%AB%E5%85%85%E5%9B%BE\" aria-label=\"填充图 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>填充图</h1>\n<p>绘制 2D 多边形以及沿 Z 轴拉伸后的 3D 图形。</p>\n<h3 id=\"shape\"><a href=\"#shape\" aria-label=\"shape permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>shape</h3>\n<p>填充图支持3种shape</p>\n<ul>\n<li>fill 绘制填充面 不支持数据映射</li>\n<li>line 绘制填充图描边 不支持数据映射</li>\n<li>extrude 对填充图3D拉伸 不支持数据映射</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">PolyonLayer<span class=\"token punctuation\">.</span><span class=\"token function\">shape</span><span class=\"token punctuation\">(</span><span class=\"token string\">'fill'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nPolyonLayer<span class=\"token punctuation\">.</span><span class=\"token function\">shape</span><span class=\"token punctuation\">(</span><span class=\"token string\">'line'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// size 表示线宽度</span>\nPolyonLayer<span class=\"token punctuation\">.</span><span class=\"token function\">shape</span><span class=\"token punctuation\">(</span><span class=\"token string\">'extrude'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// size 表示高度</span>\n</code></pre></div>\n<p>其他方法,事件,同基类 <a href=\"/zh/docs/api/layer/layer\">Layer</a></p>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-911c24b01efa22013e3bfb6511012c6c-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-22d5cfaea43f5168ac21fe86d535648f-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-22d5cfaea43f5168ac21fe86d535648f-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-2703c8487a1fc763376587f66eeacf7d-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/source/geojson/#geojson-%E6%95%B0%E6%8D%AE%E4%BB%8B%E7%BB%8D\">geojson 数据介绍</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/source/geojson/#%E7%AE%80%E4%BB%8B\">简介</a></li>\n<li>\n<p><a href=\"/zh/docs/api/source/geojson/#geojson%E7%9B%B8%E5%85%B3%E7%9A%84js%E5%BA%93\">Geojson相关的JS库</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/source/geojson/#%E5%9C%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7\">地理统计分析工具</a></li>\n<li><a href=\"/zh/docs/api/source/geojson/#%E5%9C%A8%E7%BA%BF%E5%B7%A5%E5%85%B7%EF%BC%9A\">在线工具:</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162511000,"key":"transformer-remark-markdown-html-eba8b84d14733129a7322c61766f8482-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-c78275703877b4c8457c7b54e97316df-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<h2 id=\"线图层\"><a href=\"#%E7%BA%BF%E5%9B%BE%E5%B1%82\" aria-label=\"线图层 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>线图层</h2>\n<h3 id=\"shape\"><a href=\"#shape\" aria-label=\"shape permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>shape</h3>\n<p>线图层支持4种 shape</p>\n<ul>\n<li>line 绘制路径图,</li>\n<li>arc 绘制弧线 通过贝塞尔曲线算法技术弧线</li>\n<li>greatcircle 大圆航线,地图两个点的最近距离不是两个点连线,而是大圆航线</li>\n<li>arc3d 3d弧线地图 3D视角</li>\n</ul>\n<p>⚠️ 弧线只需要设置起始点坐标即可</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"> new LineLayer()\n .source(data, {\n parser: {\n type: 'csv',\n x: 'lng1',\n y: 'lat1',\n x1: 'lng2',\n y1: 'lat2',\n },\n })</code></pre></div>\n<p>如果geojson 数据绘制弧线图 coordinates 第一对坐标为起点,第二对为终点</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n "type": "FeatureCollection",\n "features": [\n {\n "type": "Feature",\n "properties": {},\n "geometry": {\n "type": "LineString",\n "coordinates": [\n [\n 106.5234375,\n 57.51582286553883\n ],\n [\n 136.40625,\n 61.77312286453146\n ]\n ]\n }\n }\n ]\n}</code></pre></div>\n<h3 id=\"size\"><a href=\"#size\" aria-label=\"size permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>size</h3>\n<p>线图层 可以设置高度</p>\n<ul>\n<li>size 类型为number 则表示 line的宽度</li>\n<li>size 类型为 [number , number] 分别表示宽度和高度</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">lineLayer<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 线的宽度为 1</span>\nlineLayer<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 宽度为1,高度2</span>\n</code></pre></div>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-397422a40e7fc67301e3758910fccfaf-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-caf747b54e8159809c3beb2b46e148a0-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/en/docs/tutorial/quickstart/#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95\">使用方法</a></p>\n<ul>\n<li><a href=\"/en/docs/tutorial/quickstart/#%E9%80%9A%E8%BF%87-cdn-%E4%BD%BF%E7%94%A8\">通过 CDN 使用</a></li>\n<li><a href=\"/en/docs/tutorial/quickstart/#%E9%80%9A%E8%BF%87-submodule-%E4%BD%BF%E7%94%A8\">通过 Submodule 使用</a></li>\n<li><a href=\"/en/docs/tutorial/quickstart/#wip-react\">WIP React</a></li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-29a5b349a805dbe1712ced55842139a3-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"使用二维统计图表代替点状符号的一种特殊复合形式,复合图表地图中常用扩展图形还有柱状图、曲线图、玫瑰图等","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-0d5e6b054ae0e4dc5ad081332b9456de-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"以形状变量中具象的图标映射的点图层,将真实地物具化为利于直观识别的图标,常用于突出信息的突出表达。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49}}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-d1d3303c6f92e074c20c0fbe3324ba42-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/layer/linelayer/#%E7%BA%BF%E5%9B%BE%E5%B1%82\">线图层</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/linelayer/#shape\">shape</a></li>\n<li><a href=\"/zh/docs/api/layer/linelayer/#size\">size</a></li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-39727a14ec623ec7ff2e3240d0462862-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/manual/tutorial/quickstart/#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95\">使用方法</a></p>\n<ul>\n<li><a href=\"/zh/docs/manual/tutorial/quickstart/#%E9%80%9A%E8%BF%87-cdn-%E4%BD%BF%E7%94%A8\">通过 CDN 使用</a></li>\n<li><a href=\"/zh/docs/manual/tutorial/quickstart/#%E9%80%9A%E8%BF%87-submodule-%E4%BD%BF%E7%94%A8\">通过 Submodule 使用</a></li>\n<li><a href=\"/zh/docs/manual/tutorial/quickstart/#wip-react\">WIP React</a></li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-8bd46bd263f790754e46a98ca9891ea9-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/layer/layer/#layer\">Layer</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/layer/#%E7%AE%80%E4%BB%8B\">简介</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></li>\n<li>\n<p><a href=\"/zh/docs/api/layer/layer/#%E9%85%8D%E7%BD%AE%E9%A1%B9\">配置项</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/layer/#visable\">visable</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#zindex\">zIndex</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#minzoom\">minZoom</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#maxzoom\">maxZoom</a></li>\n</ul>\n</li>\n<li><a href=\"/zh/docs/api/layer/layer/#%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6\">鼠标事件</a></li>\n<li>\n<p><a href=\"/zh/docs/api/layer/layer/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/layer/#source\">source</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#scale\">scale</a></li>\n<li>\n<p><a href=\"/zh/docs/api/layer/layer/#size\">size</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/layer/#sizevalue%EF%BC%89\">size(value)</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#sizefield\">size(field)</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#sizefield-callback\">size(field, callback)</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/layer/layer/#color\">color</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/layer/#colorvalue\">color(value)</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#colorfield-colors\">color(field, colors)</a></li>\n</ul>\n</li>\n<li><a href=\"/zh/docs/api/layer/layer/#shape\">shape</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#style\">style</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#show\">show</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#hide\">hide</a></li>\n<li><a href=\"/zh/docs/api/layer/layer/#fitbounds\">fitBounds</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-c233b77d35e08201ab64c4861488d352-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"填充地图的增强实现,通过三维视角中的高度体现数据差异。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":28,"offset":27},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":28,"offset":27},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":28,"offset":27}}}}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-ad3a0411bb469460edbd1820d1a953f5-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-0b3dfbbedf9555fe75466ff56f3ff5db-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<h1 id=\"imagelayer\"><a href=\"#imagelayer\" aria-label=\"imagelayer permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>ImageLayer</h1>\n<h2 id=\"简介\"><a href=\"#%E7%AE%80%E4%BB%8B\" aria-label=\"简介 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>简介</h2>\n<p>将图片添加到地图上,需要指定图片的经纬度范围</p>\n<h3 id=\"代码示例\"><a href=\"#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B\" aria-label=\"代码示例 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>代码示例</h3>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> layer <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">ImageLayer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nlayer<span class=\"token punctuation\">.</span><span class=\"token function\">source</span><span class=\"token punctuation\">(</span>\n <span class=\"token string\">'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg'</span><span class=\"token punctuation\">,</span>\n <span class=\"token punctuation\">{</span>\n parser<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n type<span class=\"token punctuation\">:</span> <span class=\"token string\">'image'</span><span class=\"token punctuation\">,</span>\n extent<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">121.168</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30.2828</span><span class=\"token punctuation\">,</span> <span class=\"token number\">121.384</span><span class=\"token punctuation\">,</span> <span class=\"token number\">30.4219</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n</code></pre></div>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-1c348fc333b039279ca33b95350216a1-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-22e40979220b547ee56864978d7eefed-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"指需要用一连串首尾闭合相等数值点的连线的图层,表示连续分布且逐渐变化的数量特征的地图,常用于等高线图、等温线图等图。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":59,"offset":58}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":59,"offset":58}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":59,"offset":58}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-e214775bf910f98457136a5495aca2a9-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-d9c8c8e6e4baf6574d8f46f3a81eba85-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-0869a152e4c719c14970127d11b61364-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-60d822501ed69ef0096233b3fb440654-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li><a href=\"/en/docs/api/l7/#%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7\">核心特性</a></li>\n<li>\n<p><a href=\"/en/docs/api/l7/#%E6%94%AF%E6%8C%81%E4%B8%B0%E5%AF%8C%E7%9A%84%E5%9B%BE%E8%A1%A8%E7%B1%BB%E5%9E%8B\">支持丰富的图表类型</a></p>\n<ul>\n<li><a href=\"/en/docs/api/l7/#%E7%82%B9%E5%9B%BE%E5%B1%82\">点图层</a></li>\n<li><a href=\"/en/docs/api/l7/#%E7%BA%BF%E5%9B%BE%E5%B1%82\">线图层</a></li>\n<li><a href=\"/en/docs/api/l7/#%E9%9D%A2%E5%9B%BE%E5%B1%82\">面图层</a></li>\n<li><a href=\"/en/docs/api/l7/#%E7%83%AD%E5%8A%9B%E5%9B%BE\">热力图</a></li>\n<li><a href=\"/en/docs/api/l7/#%E6%A0%85%E6%A0%BC%E5%9C%B0%E5%9B%BE\">栅格地图</a></li>\n</ul>\n</li>\n<li><a href=\"/en/docs/api/l7/#l7-20-roadmap\">L7 2.0 Roadmap</a></li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-9850acf2f0d1dba77931250ff1ae1833-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"填充图,也叫分级统计图,指用一连串首尾闭合的点坐标对来表达的面图层,常用表达区域范围具有分类现象的面状分布。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162510000,"key":"transformer-remark-markdown-html-48a94297bc9dd247077cfc25bb30bedf-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-d472877a984a12546079e673e84f8ab3-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-1007c079d6357b1b7f036a12841ae440-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"区域范围内数据具有的一定热度分级分布情况的聚合面状现象,常用于描述人群分布、密度和变化趋势等。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":48,"offset":47}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":48,"offset":47}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":48,"offset":47}}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-0ce38f6fc0207c9629c6165b2f176cd7-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/source/source/#source\">Source</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/source/source/#%E6%A6%82%E8%BF%B0\">概述</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/source/source/#api\">API</a></p>\n<ul>\n<li>\n<p><a href=\"/zh/docs/api/source/source/#parser\">parser</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/source/source/#geojson\">geojson</a></li>\n<li><a href=\"/zh/docs/api/source/source/#json\">json</a></li>\n<li><a href=\"/zh/docs/api/source/source/#csv\">csv</a></li>\n<li><a href=\"/zh/docs/api/source/source/#image\">image</a></li>\n<li><a href=\"/zh/docs/api/source/source/#raster\">raster</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/source/source/#transforms\">transforms</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/source/source/#map\">map</a></li>\n<li><a href=\"/zh/docs/api/source/source/#grid\">grid</a></li>\n<li><a href=\"/zh/docs/api/source/source/#hexagon\">hexagon</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-d1d3303c6f92e074c20c0fbe3324ba42-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<h2 id=\"线图层\"><a href=\"#%E7%BA%BF%E5%9B%BE%E5%B1%82\" aria-label=\"线图层 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>线图层</h2>\n<h3 id=\"shape\"><a href=\"#shape\" aria-label=\"shape permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>shape</h3>\n<p>线图层支持4种 shape</p>\n<ul>\n<li>line 绘制路径图,</li>\n<li>arc 绘制弧线 通过贝塞尔曲线算法技术弧线</li>\n<li>greatcircle 大圆航线,地图两个点的最近距离不是两个点连线,而是大圆航线</li>\n<li>arc3d 3d弧线地图 3D视角</li>\n</ul>\n<p>⚠️ 弧线只需要设置起始点坐标即可</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"> new LineLayer()\n .source(data, {\n parser: {\n type: 'csv',\n x: 'lng1',\n y: 'lat1',\n x1: 'lng2',\n y1: 'lat2',\n }\n })</code></pre></div>\n<p>如果geojson 数据绘制弧线图 coordinates 第一对坐标为起点,第二对为终点</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n "type": "FeatureCollection",\n "features": [\n {\n "type": "Feature",\n "properties": {},\n "geometry": {\n "type": "LineString",\n "coordinates": [\n [\n 106.5234375,\n 57.51582286553883\n ],\n [\n 136.40625,\n 61.77312286453146\n ]\n ]\n }\n }\n ]\n}</code></pre></div>\n<h3 id=\"size\"><a href=\"#size\" aria-label=\"size permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>size</h3>\n<p>线图层 可以设置高度</p>\n<ul>\n<li>size 类型为number 则表示 line的宽度</li>\n<li>size 类型为 [number , number] 分别表示宽度和高度</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">lineLayer<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 线的宽度为 1</span>\nlineLayer<span class=\"token punctuation\">.</span><span class=\"token function\">size</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 宽度为1,高度2</span>\n</code></pre></div>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-6c5f52476ed9cd6ea8b7eabc064e76b2-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"指地图上可用一个形状大小相同的点状符号来定位,用表达离散现象分布特征的地图,如人口、农作物、动植物等的分布。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":55,"offset":54}}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-1294fb759b9f52825afbf490561c7d81-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/en/docs/api/layer/layer/#layer\">Layer</a></p>\n<ul>\n<li><a href=\"/en/docs/api/layer/layer/#%E7%AE%80%E4%BB%8B\">简介</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></li>\n<li>\n<p><a href=\"/en/docs/api/layer/layer/#%E9%85%8D%E7%BD%AE%E9%A1%B9\">配置项</a></p>\n<ul>\n<li><a href=\"/en/docs/api/layer/layer/#visable\">visable</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#zindex\">zIndex</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#minzoom\">minZoom</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#maxzoom\">maxZoom</a></li>\n</ul>\n</li>\n<li><a href=\"/en/docs/api/layer/layer/#%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6\">鼠标事件</a></li>\n<li>\n<p><a href=\"/en/docs/api/layer/layer/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li><a href=\"/en/docs/api/layer/layer/#source\">source</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#scale\">scale</a></li>\n<li>\n<p><a href=\"/en/docs/api/layer/layer/#size\">size</a></p>\n<ul>\n<li><a href=\"/en/docs/api/layer/layer/#sizevalue%EF%BC%89\">size(value)</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#sizefield\">size(field)</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#sizefield-callback\">size(field, callback)</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/en/docs/api/layer/layer/#color\">color</a></p>\n<ul>\n<li><a href=\"/en/docs/api/layer/layer/#colorvalue\">color(value)</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#colorfield-colors\">color(field, colors)</a></li>\n</ul>\n</li>\n<li><a href=\"/en/docs/api/layer/layer/#shape\">shape</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#style\">style</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#show\">show</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#hide\">hide</a></li>\n<li><a href=\"/en/docs/api/layer/layer/#fitbounds\">fitBounds</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-7e48b5323892c7cf647cf8590e3a5578-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<p>指地图上可用一个形状相同、大小和与其代表的数值成固定比率的圆点符号来定位的点图层,用于表达离散现象分布特征的地图。</p>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-eba8b84d14733129a7322c61766f8482-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-3b51eb4af3d4a5698e9dc244ba9364a5-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<h1 id=\"geojson-数据介绍\"><a href=\"#geojson-%E6%95%B0%E6%8D%AE%E4%BB%8B%E7%BB%8D\" aria-label=\"geojson 数据介绍 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>geojson 数据介绍</h1>\n<h2 id=\"简介\"><a href=\"#%E7%AE%80%E4%BB%8B\" aria-label=\"简介 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>简介</h2>\n<p>GeoJSON是一种对各种地理数据结构进行编码的格式。GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。</p>\n<p><a href=\"\">geojson详细文档</a></p>\n<h2 id=\"geojson相关的js库\"><a href=\"#geojson%E7%9B%B8%E5%85%B3%E7%9A%84js%E5%BA%93\" aria-label=\"geojson相关的js库 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Geojson相关的JS库</h2>\n<h3 id=\"地理统计分析工具\"><a href=\"#%E5%9C%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7\" aria-label=\"地理统计分析工具 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>地理统计分析工具</h3>\n<p><a href=\"http://turfjs.org/\" target=\"_self\" rel=\"nofollow\">turfjs</a>: 地理数据计算,处理,统计,分析的Javascript 库</p>\n<h3 id=\"在线工具:\"><a href=\"#%E5%9C%A8%E7%BA%BF%E5%B7%A5%E5%85%B7%EF%BC%9A\" aria-label=\"在线工具: permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>在线工具:</h3>\n<p><a href=\"http://geojson.io/\" target=\"_self\" rel=\"nofollow\">http://geojson.io/</a> 可以在线查看,绘制,修改GeoJSON数据</p>\n<p><a href=\"https://mapshaper.org/\" target=\"_self\" rel=\"nofollow\">https://mapshaper.org/</a> 可以查看较大的geojson,还能够简化GeoJSON数据</p>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-29a5b349a805dbe1712ced55842139a3-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<p>使用二维统计图表代替点状符号的一种特殊复合形式,复合图表地图中常用扩展图形还有柱状图、曲线图、玫瑰图等</p>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-4ddb72039f738ffb6fc8c7ca02770db1-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/component/control/#control\">control</a></p>\n<ul>\n<li>\n<p><a href=\"/zh/docs/api/component/control/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/control/#option\">option</a></li>\n<li><a href=\"/zh/docs/api/component/control/#scene-%E5%86%85%E7%BD%AE%E5%9C%B0%E5%9B%BE%E7%BB%84%E4%BB%B6\">scene 内置地图组件</a></li>\n<li><a href=\"/zh/docs/api/component/control/#zoom\">Zoom</a></li>\n<li><a href=\"/zh/docs/api/component/control/#scale\">Scale</a></li>\n<li><a href=\"/zh/docs/api/component/control/#attribution\">attribution</a></li>\n<li><a href=\"/zh/docs/api/component/control/#layer\">layer</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/control/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/control/#onadd\">onAdd</a></li>\n<li><a href=\"/zh/docs/api/component/control/#addto\">addTo</a></li>\n<li><a href=\"/zh/docs/api/component/control/#setposition\">setPosition</a></li>\n<li><a href=\"/zh/docs/api/component/control/#remove\">remove</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/control/#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81\">示例代码</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/control/#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9B%BE%E4%BE%8B%E6%8E%A7%E4%BB%B6\">自定义图例控件</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a href=\"/zh/docs/api/component/control/#faq\">FAQ</a></li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-8ba6e770aca269ce1a09e219ea919f44-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/component/marker/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0\">构造函数</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/marker/#option\">option</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/marker/#%E6%96%B9%E6%B3%95\">方法</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/marker/#setlnglat\">setLnglat</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#addto\">addTo</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#remove\">remove</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#getelement\">getElement</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#getlnglat\">getLngLat</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#togglepopup\">togglePopup</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#setpopup\">setPopup</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#getpopup\">getPopup</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li>\n<p><a href=\"/zh/docs/api/component/marker/#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81\">示例代码</a></p>\n<ul>\n<li>\n<ul>\n<li><a href=\"/zh/docs/api/component/marker/#%E9%BB%98%E8%AE%A4marker\">默认Marker</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#%E8%87%AA%E5%AE%9A%E4%B9%89marker\">自定义Marker</a></li>\n<li><a href=\"/zh/docs/api/component/marker/#%E8%AE%BE%E7%BD%AE-popup\">设置 popup</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-29a5b349a805dbe1712ced55842139a3-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"使用二维统计图表代替点状符号的一种特殊复合形式,复合图表地图中常用扩展图形还有柱状图、曲线图、玫瑰图等","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":52,"offset":51}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157450000,"key":"transformer-remark-markdown-toc-7bb76714df549123e99e9b48d8d6822f-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/zh/docs/api/layer/pointlayer/#pointlayer\">PointLayer</a></p>\n<ul>\n<li>\n<p><a href=\"/zh/docs/api/layer/pointlayer/#%E7%AE%80%E4%BB%8B\">简介</a></p>\n<ul>\n<li>\n<p><a href=\"/zh/docs/api/layer/pointlayer/#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B\">代码示例</a></p>\n<ul>\n<li><a href=\"/zh/docs/api/layer/pointlayer/#%E5%9F%BA%E6%9C%AC%E5%9B%BE%E5%BD%A2%E6%98%BE%E7%A4%BA%E7%A4%BA%E4%BE%8B\">基本图形显示示例</a></li>\n<li><a href=\"/zh/docs/api/layer/pointlayer/#%E7%AC%A6%E5%8F%B7%E5%9B%BE\">符号图</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>"}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-eba8b84d14733129a7322c61766f8482-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":1,"offset":0}}}}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829162511000,"key":"transformer-remark-markdown-html-c4cd085970d775329dc03e58519d79fd-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-7e48b5323892c7cf647cf8590e3a5578-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"指地图上可用一个形状相同、大小和与其代表的数值成固定比率的圆点符号来定位的点图层,用于表达离散现象分布特征的地图。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":58,"offset":57},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":58,"offset":57},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":58,"offset":57}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-ast-89764a64063045f6021242fe828f7bb0-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"指需要用一连串首尾不闭合的点坐标对来定位的线图层,通常用来表示轨迹,线路,道路等","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":41,"offset":40},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":41,"offset":40},"indent":[]}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":41,"offset":40}}}}
|
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157449000,"key":"transformer-remark-markdown-toc-63d6f29612923eb1f263a3a7fbc0d504-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":"<ul>\n<li>\n<p><a href=\"/en/docs/manual/tutorial/quickstart/#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95\">使用方法</a></p>\n<ul>\n<li><a href=\"/en/docs/manual/tutorial/quickstart/#%E9%80%9A%E8%BF%87-cdn-%E4%BD%BF%E7%94%A8\">通过 CDN 使用</a></li>\n<li><a href=\"/en/docs/manual/tutorial/quickstart/#%E9%80%9A%E8%BF%87-submodule-%E4%BD%BF%E7%94%A8\">通过 Submodule 使用</a></li>\n<li><a href=\"/en/docs/manual/tutorial/quickstart/#wip-react\">WIP React</a></li>\n</ul>\n</li>\n</ul>"}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"expireTime":9007200829157445000,"key":"transformer-remark-markdown-html-ast-0d5e6b054ae0e4dc5ad081332b9456de-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"以形状变量中具象的图标映射的点图层,将真实地物具化为利于直观识别的图标,常用于突出信息的突出表达。","position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49}}}],"position":{"start":{"line":1,"column":1,"offset":0},"end":{"line":1,"column":50,"offset":49}}}}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue