how to load images used in elm code with webpack 2? - webpack-dev-server

Suppose i have this view function:
view: Model -> Html Msg
view model =
img [ src "static/img/elm.jpg" ] []
How to make sure webpack 2 knows about it and loads it inside the dist folder as expected?
I found elm-asssets-loader package here - which is build for this scenario - but i don't understand how to use it.
my webpack.config.js is:
module: {
rules: [
...
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
use: [{
loader: 'elm-hot-loader'
},
{
loader: 'elm-webpack-loader?verbose=true&warn=true&debug=true'
},
{
loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath'
},
]
},
]
}
I've seen elmAssetsLoader and fileLoader custom functions mentioned inside the docks - but is not clear where to put them. I tried placing them inside module.exports object, inside modules, inside plugins.. every time i get this error:
Webpack has been initialized using a configuration object that does not match the API schema...
I also tried placing the elm-assets-loader before and after the elm--webpack-loader. When placed after elm-webpack-loader - i get an error inside the Main.elm file - which is wired because the Main.elm is just fine. Nothing wrong with it.
And when i place it before elm-webpack-loader absolutely nothing happens. Not even a warning message.
I also have the 2 modules as instructed:
-- module MyAssets exposing (..)
--
-- type AssetPath
-- = AssetPath String
--
-- elmImage : AssetPath
-- elmImage =
-- AssetPath "../static/img/elm.jpg" -- this is the location of my image, and it's correct.
--
and a view module with the image:
module View exposing (..)
view =
img [ src "what to put in here?" ] []
I'm new to webpack and that's probably why is not obvious to me what should i do. I want to understand the big picture. How things are wired.
What should i have inside my Html.Attributes.src function ?
I blindly tried many things. None of them worked. I lack the intuition.
Can somebody please provide a clear implementation of how this elm image/assets loading actually works in webpack 2? Thanks :)

I would simply copy these images with Copy Webpack Plugin. In your webpack config plugins list push this:
new CopyWebpackPlugin({
from: '',
to: ''
})
Another way is to manage images from CSS and use file-loader:
{
test: /\.(jpg|png)$/,
use: `file-loader?${ objToUrlParameters({
name: 'assets/img/[name].[hash:6].[ext]',
publicPath: options.publicPath
})
}`
},

I also tried placing the elm-assets-loader before and after the elm--webpack-loader
elm-assets-loader takes the output of elm-webpack-loader and looks for asset paths in the compiled JavaScript. As webpack applies loaders in the use config from bottom to top, you want something like
use: [{
loader: 'elm-hot-loader'
},
{
loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath'
},
{
loader: 'elm-webpack-loader?verbose=true&warn=true&debug=true'
},
]
And when i place it before elm-webpack-loader absolutely nothing happens. Not even a warning message.
This could be from not specifying the correct package in the loader config. If your elm-package.json's repository is something that is not "https://github.com/user/project.git", you need to specify the package:
// when the repository is "https://github.com/alon/elmapp.git"
loader: 'elm-assets-loader?module=MyAssets&tagger=AssetPath&package=alon/elmapp'
This is needed because elm-assets-loader looks for JavaScript code that looks like:
_<package-user>$<package-project>$<module>$<tagger>("../static/img/elm.jpg")
and if the package isn't correctly configured, it fails to find what it's supposed to find.
img [ src "what to put in here?" ] []
You need a helper function to pull out the string value contained in the AssetPath variable.
module MyAssets exposing(AssetPath(..), path, elmImage)
path : AssetPath -> String
path (AssetPath str) =
str
--
view =
img [ src <| MyAssets.path <| MyAssets.elmImage ] []

I've ended up using CopyWebpackPlugin from here.
plugins: [
...
new CopyWebpackPlugin([
{ from: './src/static/img', to: 'img' }
])
]
I doesn't work with async stuff form what i've read - but is good enough for what i needed here.
I will wait for another answer to mark it as accepted - if it can provide a solution using a loader. Until then, folks having this issue can try using this copy plugin.

Related

How can I make an ICU data file with information for emojis only

I'm trying to pare down the libicudata.a file to the bare minimum that would still allow me to be able to test the following:
u_stringHasBinaryProperty(icu::UnicodeString::fromUTF8("🤙🏿").getBuffer(), -1, UProperty::UCHAR_RGI_EMOJI);
As per the instructions found here, I crafted the following file file and used it accordingly when configuring ICU's build.
{
"strategy": "additive",
"resourceFilters": [
{
"categories": [
"misc"
],
"files": {
"includelist": [
"emoji-sequences",
"emoji-zwj-sequences"
]
},
"rules": []
}
]
}
I did end up with a (much) smaller file (17kb) but it's obviously not working. M code compiles, links and runs but fails the test.
The good folks at icu-support#lists.sourceforge.net helped me out. The information was (temporarily) missing from their documentation. The following filter is what I was looking for:
{
"strategy": "additive",
"featureFilters": {
"uemoji": "include"
}
}

Gatsby - How to query for all YAML in a subfolder of src/data/ using GraphQL

I'm trying to query for all YAML files in a subfolder of my data folder. I'm using gatsby-transformer-yaml to parse the YAML data. My filetree looks something like this:
content/
posts/
book1.md
book2.md
src/
data/
books/
quotes1.yaml
quotes2.yaml
templates/
booknote.tsx
According to the documentation, I should be able to make a query called allBooksYaml which would return all of the quotes in quote1.yaml and quote2.yaml. However, when I look at the GraphiQL playground, the only queries I can make are allQuote1Yaml and allQuote2Yaml. (1) Is this a bug? Or is something wrong with my setup?
The reason why I want to do this is so that I can filter the result of allBooksYaml with the title of the book and display the correct quotes for each page generated with the booknote.tsx template. If I don't do this, I think I would have to make an individual page/GraphQL query manually for each book note post I want to create. (2) Is there a better way to link data in a YAML file and the Markdown/Page component?
Thanks in advance!
According to the plugin's documentation, given:
module.exports = {
plugins: [
`gatsby-transformer-yaml`,
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src/data/`,
},
},
],
}
Where the source folder ${__dirname}/src/data/ contains the .yaml files.
Having in mind also, that you can structure your folder to generate an array or a single object:
Array of Objects: Where each file represents a collection. (you probably want this one)
Single Object: Where each subfolder represents a collection; each file represents one “record”.
So, if your path is ./src/data/books you should be able to query for all books, but this will generate a specific node for all books (single object).
For the second question, I think the best optimal solution is to generate dynamically the pages using gatsby-node.js, querying all markdown books and there, send the title (or another unique field) to the template via context and filter there for each specific book, so your quotes will need to contain a field with an identifier that will match the book, mostly what you said but without the manual approach. Which, at the same time, is more or less a blog approach.
Further reference: https://www.gatsbyjs.com/docs/creating-and-modifying-pages/
You should be able to do just that by using the following config:
"gatsby-transformer-yaml",
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/src/data`,
},
},
"gatsby-transformer-yaml",
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/content`,
},
},

gatsby-plugin-mdx with rehype-autolink-headers only working with wrap option

I am trying to get my site setup with Gatsby + MDX. I am looking at the documentation here and want to make use of the autolink-header-option. I have tried using the rehype and remark plugins for this, but I can only get the Rehype plugin to work and only with the wrap option. I would much prefer the GitHub (default) style with the link coming before the title.
I am using the below config in gatsby-config.js and cleared .cache and public after updating the file to be sure nothing was cached. Also I am not getting any errors, everything builds and runs successfully, there just is not any link to the headers.
{
resolve: `gatsby-plugin-mdx`,
options: {
rehypePlugins: [
// To pass options, use a 2-element array with the
// configuration in an object in the second element
require("rehype-autolink-headings"),
],
},
},
UPDATE
After trying multiple configurations, the way I was able to get it working as expected was with a different plugin config.
{
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [ `gatsby-remark-autolink-headers` ],
plugins: [ `gatsby-remark-autolink-headers` ],
},
}
Both gatsbyRemarkPlugins and plugins are required as per: https://github.com/gatsbyjs/gatsby/issues/15486
The README for rehype-autolink-headings mentions that:
This package works with headings that have IDs. One way to add IDs to headings is by using remark-slug before this plugin.
Changing your config to the following should fix it:
{
resolve: `gatsby-plugin-mdx`,
options: {
rehypePlugins: [
require("rehype-slug"),
// To pass options, use a 2-element array with the
// configuration in an object in the second element
require("rehype-autolink-headings"),
],
},
},
In fact, the documentation you linked to has this additional require line as well, but it doesn't clarify what it is used for.

How do you change the name of the default export of a folder in React?

Naturally in React you can alias importing ./component/<name>/index.js as ./component/<name>.
Is there a way in Webpack to change the name of the file that is used as the default? In this case, changing the index.js to a different file name?
JavaScript and by extension Webpack only allows index.js files as default when a directory is used. However, when using Webpack it is possible to write a plugin tapping into a hook for before-existing-directory and return the file you require as index at build time.
Luckily, this plugin is already written directory-named-webpack-plugin.
var DirectoryNamedWebpackPlugin = require("directory-named-webpack-plugin");
resolve: {
plugins: [
new DirectoryNamedWebpackPlugin()
]
}
If there is a folder named foo, this makes webpack look for foo/foo.js instead of the default index file. It also supports a custom transform function, so you can choose the file that gets selected, but I would strongly advise against that as it can get confusing real fast.
Looks like I was just missing an object layer. I had:
plugins: [
new DirectoryNamedWebpackPlugin()
]
instead of:
resolve: {
plugins: [
new DirectoryNamedWebpackPlugin()
]
}

ExtJS MVC application customized location parameters

Is it possible to load store/model/view with custom parameters?
I have structure like this:
- app/
- app/store/mystore.js
- app/model/mymodel.js
- app/view/myview.js
- app.js
- index.html
app.js content
Ext.application({
models: [
'mymodel'
],
stores: [
'mystore'
],
views: [
'mystore'
],
...
Browser loads those 3 files like this:
http://localhost/myapp/app/store/mystore.js
Is it possible to load them somehow with extra params like this: http://localhost/myapp/app/store/mystore.js?myparam=foo
First: You cannot do it separate per file!
But there are at least two ways to archive it:
You could either override the loadScript and loadScriptFile to modify the url or always use disableCaching: true and modify the disableCachingParam like so myparam=foo&_dc
Now each file would be loaded like
http://localhost/myapp/app/store/mystore.js?myparam=foo&_dc=3242423423
http://localhost/myapp/app/model/mymodel.js?myparam=foo&_dc=3242423434
http://localhost/myapp/app/view/myview.js?myparam=foo&_dc=3242423489
Have you tried routes? There is a module which you can download from :
Ext.ux.Router

Resources