Why can't files introduced by require.context() be dynamically updated in Vue? - vue.js

I am building an static markdown blog website using Vue3,and I am using require.context() to load markdown files.
This is the project structure,and I load files from static/posts.
├── dist
│   ├── assets
│   │   └── static
│   │   └── posts
│   │   ├── dev-first-vue3-todolist.md
│   │   ├── dev-fix-missing-xcrun.md
├── package.json
├── src
│   ├── App.vue
│   ├── main.js
├── static
│   └── posts
│   ├── dev-first-vue3-todolist.md
│   ├── dev-fix-missing-xcrun.md
└── vue.config.js
Here's how I load these markdown files.
let context = require.context("../static/posts", true, /\.md$/, "sync");
let keys = context.keys();
// the markdown file list
const postRawList = [];
keys.forEach((key) => {
const raw = context(key).default;
postRawList.push(raw);
});
It worked well. I can read postRawList from static/posts and render them by markdown parser.
The point is, I want my blog website static, so when I build this Vue app I use copy-webpack-plugin to copy these markdown files from static/posts to dist/assets/static/posts and it worked well.
config.plugins.push(
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, "static/posts"),
to: path.resolve(__dirname, "dist/assets/static/posts"),
},
],
})
);
I want to manage my markdown posts only by adding or deleting markdown files in dist/assets/static/posts.
But after I changing the markdown files in dist/assets/static/posts(like delete dev-first-vue3-todolist.md) ,the markdown object list(postRawList) doesn't be updated.
The markdown list is the same as the markdown list in static/posts , and no matter how I change files in this 2 posts folder,it does't be updated.
I guess it is caused by "require cache", and I had tried to delete cache after changing the files, but it did't work.
delete require.cache[context.id];
So I want to know why the file objects not be updated after I built the app and change the files in markdown directory(loaded by require.context()).
This is my first time asking questions on stackoverflow,and I feel sorry if I didn't make it clear.

Related

How to add another page to vuepress blog?

I want to add another page to vuepress with the blog plugin.
The new page that I added does not show the content.
I expect the about page to show the content
I use basic vuePressBlog template. My tree structure is
├── examples
│   ├── about
│   │   └── Readme.md
│   └── _posts
│   ├── 2018-4-4-intro-to-vuepress.md
│   ├── 2019-6-8-intro-to-vuepress-next.md
│   ├── 2019-6-8-shanghai.md
│   ├── 2019-6-8-summary.md
│   └── 2019-6-8-vueconf.md
├── index.js
├── layouts
│   ├── GlobalLayout.vue
│   ├── Layout.vue
│   ├── Post.vue
│   └── Tag.vue
├── package.json
├── package-lock.json
└── README.md
I added the following lines to the ./example/.vuepress/config.js
module.exports = {
title: "SlimBlog",
theme: require.resolve("../../"),
themeConfig: {
// Please keep looking down to see the available options.
nav: [
{
text: "Home",
link: "/",
},
{
text: "about",
link: "/about/",
},
{},
],
},
};
I assume there might be a layout missing but I unable to find the config for this.

unable to import local wasm npm package in shadow-cljs project

I am playing arounf trying to import wasm packages in my shadow-cljs project. It is bundled in a npm package, but i keep getting this error:
The required JS dependency "canvas" is not available, it was required by "canvas/core.cljs".
this is my project structure:
. <- root of the rust crate
├── canvas
│   ├── env
│   ├── node_modules
│   │   ├── ...
│   │   ├── canvas -> ../../pkg <- my local package
│   │   └── ...
│   ├── resources
│   ├── src
│   └── target
├── pkg <- my local package
├── src
├── target
└── tests
and this is my package.json (from the clojurescript project):
{
"devDependencies": {
"shadow-cljs": "^2.8.83"
},
"dependencies": {
"canvas": "file:../pkg",
"create-react-class": "^15.6.3",
"react": "^16.4.0",
"react-dom": "^16.4.0"
}
}
I ran npm install and added the canvas module to my project like so (in core.cljs):
(ns canvas.core
(:require
...
["canvas" :as canvas]))
What seems to be the problem here??
WebAssembly "bundling" is not supported by shadow-cljs.

Show different sidebar based on the current page

Is it possible to show different sidebars depending on what section of the site you're in? So if I had two sections (Books and Countries) then I could show the corresponding sidebar menu object:
module.exports = {
books: {
"Children's Book": [
"books/childrens-books/winnie-the-pooh",
"books/childrens-books/harry-potter",
],
"Non-Fiction": [
"books/non-fiction/hitchikers-guide",
"books/non-fiction/a-history-of-england",
]
},
countries: {
"Europe": [
"countries/europe/england",
"countries/europe/france",
"countries/europe/spain",
],
"Asia": [
"countries/asia/china",
"countries/asia/india",
"countries/asia/laos",
],
},
}
The docs do reference that something like this could be done, but there aren't any examples to go along with it:
You can have multiple sidebars for different Markdown files by adding more top-level keys to the exported object.
The only other place I can find sidebars referenced is in docusaurus.config.js, but I'm not sure what this section is for:
presets: [
[
'#docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
},
...
Any pointers appreciated!
So the issue was that my content structure didn't match what I had in sidebar.js. This is my content structure now:
docs
├── README.md
├── books
│   ├── childrens-books
│   │   ├── harry-potter.md
│   │   └── winnie-the-pooh.md
│   └── non-fiction
│   ├── a-history-of-england.md
│   └── hitchikers-guide.md
└── countries
├── asia
│   ├── china.md
│   ├── india.md
│   └── laos.md
└── europe
├── england.md
├── france.md
└── spain.md
├── docs
├── docusaurus.config.js
├── sidebars.js
└── src
I think the issue lay in the fact that Docusaurus couldn't find the articles I was referencing, so it just didn't parse.
With this set up URLs like localhost:3000/docs/books/childrens-books/harry-potter will work fine, but localhost:3000/docs/books/childrens-books/ will return a blank page since there's no corresponding article for that URL.

How to ignore custom elements in VuePress to avoid the "Unknown custom element" error?

I am creating documentation for a W3C web components library (Vanilla JavaScript) using VuePress. However, my "custom" web components are generating an error due to VuePress trying to "recognize" them as Vue components the very first time the page loads.
Once the page is loaded my web components work as expected, but the error is there anyway.
This is the error I am getting:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <nova-timeline> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <TimeLineWrapper> at docs/.vuepress/components/TimeLineWrapper.vue
I have created the following structure related to Vuepress
.
├── docs
│   ├── .vuepress
│   │   ├── components
│   │   │   ├── TimeLineWrapper.vue
│   │   ├── config.js
│   │   └── theme
│   ├── README.md
│   ├── components
│   │   ├── README.md
│   │   └── Timeline.md
And this is part of my code:
// docs/.vuepress/components/TimeLineWrapper.vue
<template>
<nova-timeline ref="timeline"></nova-timeline>
</template>
<script>
import timeLineJson from "./data/TimeLineData";
export default {
data() {
return {
timeLineJson: timeLineJson
};
},
mounted() {
this.$refs.timeline.data = this.timeLineJson.data;
this.$refs.timeline.configuration = this.timeLineJson.configuration;
}
};
</script>
// This is my W3C web component:
<nova-timeline ref="timeline"></nova-timeline>
What I like to know is how to "ignore custom components", I mean where or how to do this kind of configuration using the VuePress way.
Vue.config.ignoredElements = [
// Use a `RegExp` to ignore all elements that start with "nova-"
// 2.5+ only
/^nova-/
]
https://v2.vuejs.org/v2/api/#ignoredElements
Thanks in advance.
I finally manage to find how to add my ignored elements,
1) Create a file named enhanceApp.js in docs/.vuepress/theme
2) Place this content inside of it:
// https://vuepress.vuejs.org/guide/custom-themes.html#app-level-enhancements
export default ({ Vue, options, router, siteData }) => {
Vue.config.ignoredElements = [
// Use a `RegExp` to ignore all elements that start with "nova-"
// 2.5+ only
/^nova-/
];
}
Now, the error will disappear since Vue will ignore our custom web components.

How can I use buck to build react-native apps for both iOS and Android

Buck sounds like a great tool for both iOS and Android projects but I have not been abel to find any information on how to use it for react-native projects.
Update
Looks like there is some work being done on this but it may not be recommended yet.
https://github.com/facebook/nuclide/issues/31#issuecomment-164897170
https://github.com/facebook/buck/tree/master/test/com/facebook/buck/js
Update 2
Product Pains link https://productpains.com/post/react-native/add-buck-as-a-build-option
Update 8/6/2017:
I tried following my steps below for integrating React Native into an iOS app with Buck but I ran into issues when using React Native 0.47. Instead I have a new simpler approach for getting React Native working with Buck on iOS by linking to prebuilt libraries. I forked the Buck sample project repo and have it working with React Native in this repo. I also updated the README in that repo with instructions for running the demo Buck React Native iOS app and how to integrate yourself.
Note there are a couple issues with this approach documented in the README that may or may not be a problem for using this in a production app.
That repo also doesn't bundle the JS for production yet.
Older answer:
I got Buck working with an iOS project. It is very much a work in progress, but works. A few notes:
I manually copied files from node_modules/react-native/React and
node_modules/react-native/Libraries (see folder structure below).
I had to add the -w and Wno-error flags to each library because the main project had treat warnings as errors and I didn't want to see all of these React Native warnings in Xcode.
You may have to add more libraries following the pattern. It also helps to look at the React Native podspec.
There is probably opportunity to clean things up like there is no need for reactnative.xcodeproj in the vendor/reactnative folder (see below).
There is probably some work needed to correctly bundle the JS for production. Currently it will only work if the JS is fetched from a server (e.g. Node.js).
Here is my vendor/reactnative/BUCK file:
apple_library(
name = 'ReactNative',
srcs = glob([
'React/**/*.m',
'React/**/*.mm',
'React/**/*.c',
'React/**/*.S',
]),
exported_headers = glob([
'React/**/*.h',
]),
system_frameworks = [
'JavaScriptCore'
],
exported_linker_flags = [
'-lc++',
],
compiler_flags = [
'-Wno-error',
'-w'
],
visibility = ['PUBLIC'],
)
apple_library(
name = 'RCTWebSocket',
srcs = glob([
'Libraries/WebSocket/*.m',
]),
headers = glob([
'React/**/*.h',
]),
exported_headers = glob([
'Libraries/WebSocket/*.h',
]),
compiler_flags = [
'-Wno-error',
'-w'
],
visibility = ['PUBLIC'],
deps = [
':ReactNative',
]
)
apple_library(
name = 'RCTNetwork',
srcs = glob([
'Libraries/Network/*.m',
]),
headers = glob([
'React/**/*.h',
]),
exported_headers = glob([
'Libraries/Network/*.h',
]),
compiler_flags = [
'-Wno-error',
'-w'
],
visibility = ['PUBLIC'],
deps = [
':ReactNative',
]
)
apple_library(
name = 'RCTText',
srcs = glob([
'Libraries/Text/*.m',
]),
headers = glob([
'React/**/*.h',
]),
exported_headers = glob([
'Libraries/Text/*.h',
]),
compiler_flags = [
'-Wno-error',
'-w'
],
visibility = ['PUBLIC'],
deps = [
':ReactNative',
]
)
apple_library(
name = 'RCTImage',
srcs = glob([
'Libraries/Image/*.m',
]),
headers = glob([
'React/**/*.h',
'Libraries/Network/*.h'
]),
exported_headers = glob([
'Libraries/Image/*.h',
]),
compiler_flags = [
'-Wno-error',
'-w'
],
visibility = ['PUBLIC'],
deps = [
':ReactNative',
':RCTNetwork'
]
)
Here is the folder structure inside a vendor folder in my project:
vendor/reactnative
├── BUCK
├── Libraries
│   ├── ART
│   ├── ActionSheetIOS
│   ├── AdSupport
│   ├── Animated
│   ├── AppRegistry
│   ├── AppState
│   ├── BatchedBridge
│   ├── BugReporting
│   ├── CameraRoll
│   ├── Components
│   ├── CustomComponents
│   ├── DebugComponentHierarchy
│   ├── Devtools
│   ├── EventEmitter
│   ├── Experimental
│   ├── Fetch
│   ├── Geolocation
│   ├── Image
│   ├── Inspector
│   ├── Interaction
│   ├── JavaScriptAppEngine
│   ├── LayoutAnimation
│   ├── Linking
│   ├── LinkingIOS
│   ├── Modal
│   ├── NativeAnimation
│   ├── NavigationExperimental
│   ├── Network
│   ├── Promise.js
│   ├── PushNotificationIOS
│   ├── QuickPerformanceLogger
│   ├── RCTTest
│   ├── RKBackendNode
│   ├── ReactIOS
│   ├── ReactNative
│   ├── Sample
│   ├── Settings
│   ├── Storage
│   ├── StyleSheet
│   ├── Text
│   ├── Utilities
│   ├── Vibration
│   ├── WebSocket
│   ├── promiseRejectionIsError.js
│   ├── react-native
│   └── vendor
├── React
│   ├── Base
│   ├── Executors
│   ├── Layout
│   ├── Modules
│   ├── Profiler
│   └── Views
└── reactnative.xcodeproj
├── project.pbxproj
└── xcuserdata
Then in the deps of my main BUCK file I add:
'//vendor/reactnative:ReactNative',
'//vendor/reactnative:RCTWebSocket',
'//vendor/reactnative:RCTText',
'//vendor/reactnative:RCTNetwork',
'//vendor/reactnative:RCTImage'
There's no official documentation / template for building RN apps with Buck yet but it shouldn't be that hard. You'd need to add a BUCK file that does the equivalent of what your build.gradle file does.
It's mostly just:
Declares an Android app with a dependency on React Native from JCenter (Buck has the android_binary rule to do that)
In release mode it also bundles the JS into your app's assets
folder. You could skip this for a start (in dev mode the app fetches the JS from localhost at runtime) but I believe Buck has built-in support for bundling JS too.