Less loader image url - node.js

I'm having trouble adding an image url to a variable in my LESS file.
I am using a project called Guide4You where I would like to add a new LESS file with my own images. This project uses node with webpack.
For my project I use this folder structure:
├── root
│ ├── load_image.png
│ ├── styles
│ │ └── substyles
│ │ ├── load.less
In the less file I have the following code:
#test: url("../../load_image.png");
Whenever I try to compile the code into webpack I get the following error:
[ './root/load_image.png
Module parse failed:
C:\projects\root\\load_image.png
Unexpected character \'�\' (1:0)\nYou may need an appropriate loader to handle this file type.
Is it possible that the less-loader sees my url as a reference to another loader and tries to execute it?

You need an appropriate loader that would match that png of yours. To solve this problem, use either url-loader or file-loader so that it matches your png.
Documentation: https://github.com/webpack-contrib/url-loader, https://github.com/webpack-contrib/file-loader

Related

React : how to load image outside src and public folders

My project as this kind of structure :
├── api
├── db
│ └── images
├── ui
│ └── public
│ └── src
│ | └── App.js
My app was created using create-react-app so I can't import files outside of src directory, and I do not want these images to be in the public folder : how can I have an img tag :
<img src="db/images/img_1.jpg">
with src getting images on db/images folder, completely outside of react app ?
Thank you for your replies
Another option is to put the image inside of your src and reference it in a react fashion. Consider the following:
├── ui
│ └── public
│ └── src
│ | └── App.js
└── img_1.jpg
app.js
import img from "./img_1.jpg";
then in your render img tag
<img src={img} />
Hoping this might work for you? iirc this will prevent someone from hotloading the image from your public folder.
If there's literally 0 way of moving the images into your react project, the only way I can think is to upload the images somewhere and reference them from a literal link, such as S3
If you just don't want it to reload when you upload a file, you can ignore the folder the files are uploaded to in you webpack config
devServer: {
...
watchOptions: {
ignored: './src/images/**/.*',
},
...
}
The create-react-app package uses a plugin for Webpack called ModuleScopePlugin that causes this behavior
You can use the package customize-cra for override the webpack configs.
The customize-cra has a method to resolve your problem.
removeModuleScopePlugin
or you can eject from create-react-app and remove this config manually at webpack

Webpack suddenly fails to compile due to "Module not found: Error: Can't resolve" errors

As of yesterday afternoon, our Javascript unit test suite has started failing. None of the tests run and webpack reports a build failure after a string of Module not found errors. Here's our build stack:
Node 6.11.5 (yes I know, very old)
Karma 1.7.1
Webpack 2.2.1
React 15.6.2
We run our unit tests using Karma. Most of the test suite involves React, so we use Webpack to build everything. To do this, we import our webpack config and then plug various values into the Karma webpack config.
Building the scripts directly using Webpack works fine, but when we try to run karma start we get a lot of these errors:
ERROR in ./~/object.entries/implementation.js
Module not found: Error: Can't resolve 'es-abstract/2019/RequireObjectCoercible' in '/jenkins/workspace/RFD/DCS/assets-build/build-js/node_modules/object.entries'
# ./~/object.entries/implementation.js 3:29-79
# ./~/object.entries/index.js
# ./~/enzyme/build/Utils.js
# ./~/enzyme/build/ReactWrapper.js
# ./~/enzyme/build/index.js
# ../sources/admin/js/pages/sponsored/organic_flyers/tests/DealerAddButton.spec.jsx
ERROR in ./~/object.fromentries/implementation.js
Module not found: Error: Can't resolve 'es-abstract/2019/AddEntriesFromIterable' in '/jenkins/workspace/RFD/DCS/assets-build/build-js/node_modules/object.fromentries'
# ./~/object.fromentries/implementation.js 3:29-79
# ./~/object.fromentries/index.js
# ./~/enzyme-adapter-utils/build/Utils.js
# ./~/enzyme-adapter-utils/build/index.js
# ./~/enzyme-adapter-react-15/build/ReactFifteenAdapter.js
# ./~/enzyme-adapter-react-15/build/index.js
# ../sources/admin/js/pages/sponsored/organic_flyers/tests/DealerAddButton.spec.jsx
ERROR in ./~/object.fromentries/implementation.js
Module not found: Error: Can't resolve 'es-abstract/2019/CreateDataPropertyOrThrow' in '/jenkins/workspace/RFD/DCS/assets-build/build-js/node_modules/object.fromentries'
# ./~/object.fromentries/implementation.js 4:32-85
# ./~/object.fromentries/index.js
# ./~/enzyme-adapter-utils/build/Utils.js
# ./~/enzyme-adapter-utils/build/index.js
# ./~/enzyme-adapter-react-15/build/ReactFifteenAdapter.js
# ./~/enzyme-adapter-react-15/build/index.js
# ../sources/admin/js/pages/sponsored/organic_flyers/tests/DealerAddButton.spec.jsx
ERROR in ./~/object.fromentries/implementation.js
Module not found: Error: Can't resolve 'es-abstract/2019/Get' in '/jenkins/workspace/RFD/DCS/assets-build/build-js/node_modules/object.fromentries'
# ./~/object.fromentries/implementation.js 5:10-41
# ./~/object.fromentries/index.js
# ./~/enzyme-adapter-utils/build/Utils.js
# ./~/enzyme-adapter-utils/build/index.js
# ./~/enzyme-adapter-react-15/build/ReactFifteenAdapter.js
# ./~/enzyme-adapter-react-15/build/index.js
# ../sources/admin/js/pages/sponsored/organic_flyers/tests/DealerAddButton.spec.jsx
All of these issues seem to be tied to es-abstract, which we noticed had a new release yesterday (1.17.0-next.1). This is right around the time everything began failing. That said, the package seems to have downloaded and installed correctly:
ubuntu#ip-172-17-108-178:/workspace/assets-build/build-js$ npm list es-abstract
admin#0.0.1 /workspace/assets-build/build-js
├─┬ enzyme#3.10.0
│ ├─┬ array.prototype.flat#1.2.3
│ │ └── es-abstract#1.17.0-next.1
│ ├─┬ object.entries#1.1.1
│ │ └── es-abstract#1.17.0-next.1
│ └─┬ string.prototype.trim#1.2.0
│ └── es-abstract#1.16.3 deduped
├─┬ enzyme-adapter-react-15#1.4.1
│ ├─┬ enzyme-adapter-utils#1.12.1
│ │ ├─┬ airbnb-prop-types#2.15.0
│ │ │ └─┬ array.prototype.find#2.1.0
│ │ │ └── es-abstract#1.16.3 deduped
│ │ └─┬ object.fromentries#2.0.2
│ │ └── es-abstract#1.17.0-next.1
│ └─┬ object.values#1.1.1
│ └── es-abstract#1.17.0-next.1
├─┬ eslint-plugin-jsx-a11y#6.2.3
│ └─┬ array-includes#3.1.0
│ └── es-abstract#1.17.0-next.1
└─┬ object.values#1.0.4
└── es-abstract#1.16.3
And when I inspect the node_modules directory manually I can see all the files I would expect to see, based on a cursory examination of the es-abstract Github. I can't figure out why Webpack apparently can't see these files despite them being installed in the correct place. I also can't figure out why this would suddenly break as of yesterday, unless something was wrong with the es-abstract package. But if that's the case, no one's reported any issues to any of the affected projects (which include Enzyme and some of the ES shims) or to the es-abstract project itself. Also, looking at the CI builds for some of the affected projects, they all still seem to report passing tests.
We're at a loss of what to do. I've tried wiping out node_modules and npm installing from scratch, upgrading Node to the v8 LTS, downgrading Enzyme and the React adapter to try and pull in an older version of es-abstract (which doesn't work, their package.json files still ask for ^1.17.0-next.1, which makes no sense to me given some of these releases are a year old). Nothing works.
It's an issue with the Webpack or Jest configuration.
Absolute and relative paths can both be used, but be aware that they will behave a bit differently.
A relative path will be scanned similarly to how Node scans for node_modules, by looking through the current directory as well as its ancestors (i.e. ./node_modules, ../node_modules, and on).
With an absolute path, it will only search in the given directory.
webpack.config.js
module.exports = {
//...
resolve: {
modules: ['node_modules']
}
};
Use relative path for node_modules
I had this issue and solved by fixing my modules resolution settings in Jest.
With the current state of things, my package-lock includes:
"array.prototype.find": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.0.tgz",
"integrity": "sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==",
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.13.0"
}
},
and
"array-includes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.0.tgz",
"integrity": "sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.0"
},
"dependencies": {
"es-abstract": {
"version": "1.17.0-next.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz",
...
This caused me to have es-abstract 1.16.3 installed in my root node_modules and 1.17.0-next.1 as a subdependency of array-includes (among others).
Having changed my Jest moduleDirectories config made my root node_modules the first lookup place. This is what Jest docs say about this option: An array of directory names to be searched recursively up and Setting this option will override the default, which happens to be node_modules.
so check your configuration for this feature:
https://jestjs.io/docs/en/configuration#moduledirectories-arraystring for jest
https://webpack.js.org/configuration/resolve/ for webpack.
I created an issue on the maintainers github repository https://github.com/ljharb/es-abstract/issues/84#issuecomment-567422831
Since we are encountering the exact same issue we went with an idea that was described by a comment. Running the webpack development build under productionflag. For us all source-map entries are kept and our development app is fully debugable. So we use that as a workaround.
If that ever breaks in future we will probably fork all the repositories that went with a semver range dependency and host it ourselves for our really outdated legacy repos.

How to get the current path of the running Yeoman generator

I have my own Yeoman generator.
I created a sub-generator to create a new view folder.
Basically, the usage is:
open a new terminal
cd into the parent folder
run the yeoman command yo my-generator:view
follow the instructions
This view sub-generator prompt a folder name.
For example:
If I want to create the view authentication on the default views directory.
cd views
yo my-generator:view
The result should be:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
Now, if I want to create a sub-view login for the authentication view.
cd views/authentication
yo my-generator:view
The result should be:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
│ ├── login
│ │ ├── login.controller.js
│ │ ├── login.template.html
Instead, the current (wrong) result is:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
├── login
│ ├── login.controller.js
│ ├── login.template.html
My struggle here is that I don't know how to get the current path when I run the command.
Actually, I just create the new folder with a default prefix path which is app/views/.
This is why Authentication example works.
However when my current path is deeper in the views folder, it will add the new folder at the root of the views folder.
If I could get the current path (of the cmd), I should be able to add this path as the prefix instead of setting a default and not static one.
This is why Login example doesn't works.
Some code example:
$that is the current generator object
$that.viewNameCamel is the name of the folder set by the user
I use a .txt file as template and then create the controller.js file.
const filePrefix = 'app/views/' + $that.viewNameCamel + '/' + $that.viewNameCamel + '.';
const exampleData = {
controllerAlias: 'vm',
otherVar: 'example'
};
$that.fs.copyTpl(
$that.templatePath('controller.txt'),
filePrefix + 'controller.js',
exampleData
);
Tried:
$that.env.cwd
process.cwd()
__dirname
path.js library
Similar:
Issue 1037
Question 28481715
So guys, do you have a clue on how do I get the current folder path ?
Is there an alternative solution here ?
Thanks !
EDIT 1:
The problem here is the .yo-rc.json present on the root directory of the projet.
The file rewrite the path so I should delete it to fix the problem.
However if I delete this file, the user configuration will no longer be saved.
And I need it for later sub-generator usage.
Is there another way to save the user configuration ?
Or once again, is there another way to get the current real path ?
I know this is kinda old but for any one who comes later,
from the documentation https://yeoman.io/authoring/file-system.html
If you want to know from where the user is running yo, then you can get the path with this.contextRoot. This is the raw path where yo was invoked from; before we determine the project root with .yo-rc.json.
from my experience removing the .yo-rc.json would mean that you need to manually check if the path provided is ok, having a fixed root point is something helpful.
Just remove the .yo-rc.json file from your root directory. This is the file that is responsible for locating your root irrespective of where you are in the file system.
I am not sure about the repercussions of removing it but nothing seem to have happened to the generators I built.
Now you can use process.cwd() and it will get the correct working directory.
For your use case to have a prefix app/views, you probably need to write some Javascript to append or not append the prefix based on where you are, which should be trivial.

test or prevent some relative path imports / requires

I have a folder structure like so:
.
└── client
├── components
└── routes
├── index.js
├── Login
│ ├── index.js
│ ├── assets
│ ├── components
│ ├── container
│ └── modules
└── UpdatePassword
├── index.js
├── assets
├── components
├── container
└── modules
I would like to see if anyone is importing files from the UpdatePassword folder to the Login folder and vice versa.
Basically I'm following a fractal project structure where I want components that are related to the UpdatePassword or Login route to only exist in their respective folders. Shared components would exist in the client/components subdirectory. To maintain a structure like this, I would like to write a test that fails when an 'unacceptable' imports or require is used. I.e. if a file in UpdatePassword imports from Login/components.
Is there a way to test or check whether an import is coming from specific folders?
Try madge: I usually run it as madge --image /path-to-folder/dependencies.png routes (There is also a exclude option if you need it)
You'll get a visual graph which shows you dependencies between files.
I have no idea about native way to do it.But you can wrap "require" function:
function myRequire(fromPath, requiredPath) {
//code to judge whether or not can load requiredPath from fromPath
var can = ...
if(can) {
return require(requiredPath);
}
else {
throw new Error(`you can not load ${requiredPath} from ${fromPath}`);
}
}

How to wire Angular2 + Webpack + Node + Express?

First of all, I have it wired and working, but I am somewhat discontent with the result and have a feeling it can be improved.
(The current result can be found here - https://github.com/MarkKharitonov/Angular2WebpackNodeExpress/tree/v0.0.1.)
The directory structure is:
C:.
│ .gitignore
│ package.json
│ tsconfig.json
│ tslint.json
│ typings.json
│ webpack.config.js
│
├───dist
│ └───server
│ api.js
│ api.js.map
│ main.js
│ main.js.map
│
└───src
├───client
│ app.component.ts
│ index.html
│ main.ts
│ polyfills.ts
│ tsconfig.json
│ vendor.ts
│
└───server
api.ts
main.ts
tsconfig.json
Right now the dist folder has only the server side files compiled from ./src/server. They are placed there by the IntelliJ IDEA, because ./src/server/tsconfig.json requests compilation on save.
The client side bundling occurs in memory courtesy of webpack-dev-server. The ./src/client/tsconfig.json does not request compilation on save.
The things I dislike about my current setup are described here - https://github.com/MarkKharitonov/Angular2WebpackNodeExpress/tree/v0.0.1#problems, namely:
webpack is going to take care of any plain .js files under ./src/client - they would be bundled and placed under ./dist/client automatically. But what about plain .js files under ./src/server ? Do I need a task runner for that (gulp, grunt, whatever ...) or is there a solution within webpack?
I have three tsconfig.json files - ./src/client/tsconfig.json, ./src/server/tsconfig.json and ./tsconfig.json. The three files share most of the options, but not all. Right now I copy them in each of the three files - not very good.
In addition, because the typings folder is at the root I have to start all the top level TypeScript files (.\src\client\main.ts, .\src\client\polyfills.ts, .\src\client\vendor.ts and .\src\server\main.ts) with /// <reference path="../../typings/index.d.ts" />.
Hence the questions:
Can webpack also handle the server side files, but differently from the client side ones? I.e. transpile - yes, copy to dist - yes, bundle - no? Please, bear in mind I am using webpack-dev-server.
Is it possible to inherit tsconfig.json configuration so that I could avoid duplicating many options across the three files I have?
Is it possible to avoid the inclusion of /// <reference path="../../typings/index.d.ts" /> in the top level TypeScript files when the file layout is similar to mine ?
I know these are three questions instead of one, but I feel they are all closely related and the answer to one could also be the answer to another.
I don't think you need/want webpack to handle server-side files. Transpiling and copying over of the server side files to /dist is handled by Typescript compiler (via outDir config), already. There will be no bundling of server-side files since no server files were indicated as entry points in the webpack config.
Is not currently possible. However, looks like there is an issue to track this: https://github.com/Microsoft/TypeScript/issues/9876
Unsure, related to #3 in a way (but not really). I'd imagine no as long as you want to keep the client and server files truly seperate.

Resources