So I'm working on this project that has a Rails-like folder structure though it's handled by Node.js tooling (Grunt as task runner). I'm using Bower to manage my vendor assets.
My folder structure looks like this:
.
└── src
├── app
│ └── assets
│ ├── javascripts
│ └── stylesheets
│ └── application.scss
├── public
└── vendor
└── bower
Basically all the development source code lives in the app/assets folder, public is where production files go and vendor is where 3rd party stuff goes.
So as you can see, I have this application.scss file. This is the stylesheet manifest I'm using. It's responsible to import all the modules that should be compiled to my final stylesheet file later.
The problem is that I don't see a sane way to reference libraries installed through Bower from inside my manifest file.
With Rails Asset Pipeline/Sprockets I would do //= require_tree vendor/bower and that would work but I don't know what's the equivalent of doing that on the context of this project.
Do you guys have any suggestion on what could I do?
Ps.: Using Grunt tasks to "handle" this is out of question.
Just configure Bower to install packages on vendor/assets/components by creating a file called .bowerrc in your root directory.
{"directory": "vendor/assets/components"}
Everything inside vendor/assets and app/assets is added to the load path, so you can just reference those files.
You may need to put the actual file you want to load. Let's say you installed the normalize-scss package. You'll probably have to add this to your application.scss file:
#import "normalize-scss/normalize";
This is just a guess, but I'd bet on it.
EDIT: This will work on Rails apps, which apparently isn't your case. So if you're using Grunt to compile SCSS, you can add the Bower directory to your load path with the loadPath option.
The Gruntfile's Sass task may look with something like this:
{
sass: {
dist: {
files: {"src/assets/stylesheets/application.scss": "public/application.css"},
options: {
loadPath: ["vendor/bower"]
}
}
}
}
To import the file, you will do something like I said above (referencing the whole file). Didn't test the Grunt configuration, but it'll probably work.
Bower downloads whole git repositories.
Example:
bower install jquery
This would create the following structure
tree vendor/bower
bower
└── jquery
├── bower.json
├── component.json
├── composer.json
├── jquery.js
├── jquery-migrate.js
├── jquery-migrate.min.js
├── jquery.min.js
├── jquery.min.map
├── package.json
└── README.md
1 directory, 10 files
It doesn't make much sense to load all those files in my opinion.
What You could do is:
create a vendor/require directory
symlink all required files into this directory:
cd vendor/require; ln -s ../bower/jquery/jquery.min.js
then require all files with ruby's help or manually
Dir['path/to/vendor/require/*.js'].each do |file_name|
puts "<script type="text/javascript" src="#{file_name}"></script>"
end
You could also use Grunt and it's concat task:
grunt.initConfig({
concat: {
options: {
separator: ';',
},
dist: {
src: ['path/to/vendor/bower/jquery/jquery.min.js', 'path/to/vendor/bower/other-package/init.min.js'],
// or if You decide to create those symlinks
// src: ['path/to/vendor/require/*'],
dest: 'path/to/public/js/built.js',
},
},
});
For compass on sass You could use:
#import 'path/to/directory/*';
Related
How can I use an external npm library in my theme to use it in the storefront?
To give an example, how would you include https://www.npmjs.com/package/slick-carousel? This gives JS- and SCSS/CSS-files inside node_modules. I know that there is an included slider with tinyslider that one could use, but the question is more about including and using the external ressoures. I couldn't find any guide/documentation about such a case unfortunately.
Please see the documentation regarding adding NPM dependencies.
You need to import the scss/css within your plugins base.scss (f.e.)
We are copying the css as scss withing install of package.json into the Resources/src/scss-Folder to have it easier to import it.
We found a solution to import styles from NPM packages.
storefront
├── build
│ └── webpack.config.js
├── dist
├── node_modules
│ └── #my-organisation
│ └── my-package
│ └── dist
│ ├── style.css
│ └── script.js
├── package-lock.json
├── package.json
└── src
└── scss
└── base.scss
In your base.scss you now can import the styles like this:
#import "../../node_modules/#my-organisation/my-package/dist/style"
The important part for CSS-Files is, that you don NOT specify the file-extension in the import, otherwise the import-statement will count as a regular CSS-import, see https://sass-lang.com/documentation/at-rules/import#importing-css
In addition to importing .sass and .scss files, Sass can import plain old .css files. The only rule is that the import must not explicitly include the .css extension, because that’s used to indicate a plain CSS #import.
I have a Create-React-App 5 project using Yarn 3 and TypeScript 4. The web app uses a library in the same repo through Yarn's portal: protocol (Yarn workspaces are not used).
myRepo
├── myLib
│ ├── package.json
│ ├── yarn.lock
│ └── src
│ ├── index.js
│ └── macro.js
├── myApp
│ ├── package.json
│ ├── yarn.lock
│ └── src
│ ├── App.tsx
│ ├── App.test.tsx
│ └── index.tsx
└── yarnrc.yml
myApp/package.json uses a portal like so:
"dependencies": {
"myLib": "portal:../myLib",
My top-level Yarn config:
# yarnrc.yml
nodeLinker: node-modules
If I substitute file: for portal:, everything works fine. Even with portal:, yarn build and yarn start within myApp still work fine, but yarn test becomes a problem: /Users/luke/myRepo/myLib/src/index.js: The macro imported from "./macro" must be wrapped in "createMacro" which you can get from "babel-plugin-macros".
Huh? I'm certainly not trying to do anything with Babel macros. Moreover, that stuff is in a library and not the app itself.
What's going on, and how do I fix it?
Okay, I think I've figured it out!
First, CRA includes babel-plugin-macros (source), which operates by looking for particular filenames such as macro.js and treating them as Babel macros (docs). So, if I had a file myApp/src/macro.js, it would error out in a similar way, but also for build/start.
Second, why is it only a problem under Jest? Jest is actually transpiling the dependency, which Webpack somehow knows not to do. Normally this would be inconsequential (apart from slowing things down), but in this case Jest's transpiling is what runs into the problem, since it wrongly tries to interpret myLib using Babel macros (which myLib's author of course never intended).
Third, why is Jest trying to transpile that other library, which lies outside myApp, in the first place? It certainly shouldn't be. Actually, Jest tries to transpile everything besides what is explicitly excluded, and the exclusion under CRA defaults to (source):
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$',
'^.+\\.module\\.(css|sass|scss)$',
],
The intent is to include the app itself and exclude its dependencies. This approach sort of assumes that all the dependencies of myApp will be somewhere under a node_modules, which (PnP aside) would be an especially reasonable expectation under nodeLinker: node-modules. But with a portal, there is a symbolic link to myLib, which is (after resolving its real path) not under any node_modules and therefore does not match the ignore patterns. Thus, dependencies accessed through portals are not excluded from Jest transformation under this config.
Solution
To solve it, configure Jest to also exclude anything not under the project's root directory, i.e., add:
'^(?!<rootDir>)'
Since I happen to be using Craco already, I can just:
// craco.config.js
module.exports = {
jest: {
configure: jestConfig => ({
...jestConfig,
transformIgnorePatterns: [
...jestConfig.transformIgnorePatterns,
'^(?!<rootDir>)',
],
}),
},
};
There really ought to be a built-in way to handle this, but 🤷♂️
I have recently packaged an electron app using electron-builder:
myProject/
├── package.json
├── app/
└── release/
All files created by electron-builder are place in the release directory. The executable works fine on my local machine, with all features present through the packaged app.
However, once I move the application to another machine only some features are available. Noticeably features within subdirectories in app/ are not included.
For example here a snippet of the app/ directory:
app/
├── app.html
├── index.js
├── components/
└── other files and folders
Features added from .js/.html files within components/ are not present when I move the app to another machine. I have tried both moving just the executable as well as the whole release/ directory, neither includes additional features beyond what is included in app.html.
Update
It does indeed look like any other machine simply doesn't read items contained in
<script></script>
In my app.html file
Would there be some outside installation I need to do on another machine to get this executable running
Found the issue,
It involved my usage of a two package.json structure
Both dependencies and devDependencies of my build were located in the root/package.json, where dependencies needed to be moved to the app/package.json file
My understanding is that Bazel expects projects to be under a monorepo with a WORKSPACE file at the top-level and BUILD files in every project:
Repo
├── ProjectA
│ └── BUILD
├── ProjectB
│ └── BUILD
└── WORKSPACE
However, going through the Bazel NodeJS rules documentation, it seems to suggest that every project should have it's own WORKSPACE file where it defines its dependencies. i.e. ...
Repo
├── ProjectA
│ ├── BUILD
│ └── WORKSPACE
└── ProjectB
├── BUILD
└── WORKSPACE
This looks similar to a multi-repo with every project referencing other projects as an external dependency, which seemed okay to me, until I realized that for external dependencies, Bazel requires all transitive dependencies to be specified in the WORKSPACE file for every package, which is definitely not ideal.
What's the easiest way to use Bazel with NodeJS projects, with some projects possibly written in other languages? Also, is there an example somewhere for Bazel being used in a multi-repo setting?
Thanks!
I think the 2 possible options are in fact
Repo
├── MyProject
│ └── BUILD
├── third_party
│ └── ProjectB
│ └─ BUILD
└── WORKSPACE
or
Repo
├── MyProject
│ └── BUILD
└── WORKSPACE
where in the second case WORKSPACE references ProjectB with npm_install rule as defined in https://github.com/bazelbuild/rules_nodejs#using-bazel-managed-dependencies
I'm still trying to figure this out myself, but what I've gathered so far is that there is only one WORKSPACE file at the root of the repo. You need to have a package.json file (probably at the root) containing all the dependencies used in the whole repo then call npm_install or yarn_install in the WORKSPACE file to download them all.
Then your package BUILD file can reference a dependency with #npm//some_package as in:
filegroup(
name = 'sources',
srcs = ['index.js'],
)
npm_package(
name = 'pkg',
srcs = [ 'package.json'],
deps = [
':sources'
'#npm//lodash'
],
)
There are a few different dependency edge cases I haven't figured out yet so this may not be perfectly correct. Good luck.
I want to create a library in Typescript that I can share via npm. Specifically, I want to use webpack to generate a js bundle along with a definition file to share the types with the js. So I'd have a tree of files like:
├── lib
│ ├── lib.d.ts
│ └── lib.min.js
├── test
...
├── ts
│ ├── errors
│ │ ├── CannotModifyAlteredObject.ts
│ ├── Lib.ts
│ ├── PostProcessors.ts
│ ├── Serializers.ts
├── tsconfig.json
├── typings.json
├── LICENSE
├── package.json
├── README.md
└── webpack.lib.config.js
And all the types exported by ts/Lib.ts would be exported to a single .d.ts in the lib directory to sit next to the js bundle.
I've looked at the following questions/sources:
Writing npm modules in typescript
How to create a typescript library (and the question it duplicates)
This unanswered question
The offical typescript guide to creating packages
This example typescript library project
And another SO question
However, none of these provide an example using webpack. Being able to bundle everything you need to use the library (apart from the nodejs runtime) into a single file is pretty important for my use case, so webpack fits this role well. I'd like to be able to generate a .d.ts file that maps to what webpack creates. However, I want to avoid creating the .d.ts file manually - it should be possible to automatically extract the types without having manually created .d.ts files get out of sync with my source code. Is there a way of doing this?