I have a custom MUI 5 component library NPM package that exports some basic components built with MUI 5, exports theme file and wraps the theme provider into reusable component like so:
import { ThemeProvider } from 'styled-components';
import { StyledEngineProvider } from '#mui/material/styles';
import { theme as defaultTheme } from './theme';
function CustomThemeProvider(props: {
theme: any;
children: JSX.Element[];
}): JSX.Element {
const { theme = defaultTheme, children } = props;
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</StyledEngineProvider>
);
}
export default CustomThemeProvider;
However when I try using this custom theme provider and the components in the project that uses this shared library, theme is not applied at all. This approach did work with MUI 4, but there was no Emotion layer at that point and setup was much simpler.
I have added all of these in peer dependencies for the shared component package to keep the references intact.
"peerDependencies": {
"#emotion/react": "^11.7.1",
"#emotion/styled": "^11.6.0",
"#mui/icons-material": "^5.2.4",
"#mui/lab": "^5.0.0-alpha.60",
"#mui/styles": "^5.2.3",
"#mui/material": "^5.2.4",
"#mui/styled-engine-sc": "^5.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"styled-components": "^5.3.3"
},
But it does not make any difference.
Any ideas how to make it work, or any other approach that allows for a shared MUI 5 component library / theme to work, are welcome!
Not sure if this is the same situation, but in my case this was a problem of using npm link for local development.
NOTE: You could also run into this problem if #mui is not listed as a peerDependency of your component package.
TLDR: If your shared component library package is installed with its own copy of #mui (i.e. /node_modules/pkg/node_modules/#mui) then your shared ThemeProvider won’t work.
I have a very similar setup, with a shared npm package (#my/custom-components) with MUI as a peer dependency. In the consuming app, I used npm link #my/custom-components.
The problem with using link is it creates a symlink to your local package, which isn’t representative of the final build. When #my/custom-components is published, it only includes the package.json and a dist/ folder. But on my local machine, it includes all the source files, including the node_modules folder.
Normally, a package with peerDependencies won’t have its own sub node_modules folder, to ensure it uses the host app’s dependencies. But with this local setup, #my/custom-components was configuring its own copy of MUI, instead of the host app’s MUI:
// When using npm link
host-app
├── node_modules
│ ├── #my/custom-components
│ │ ├── dist
│ │ ├── node_modules
│ │ │ └── #mui/material-ui <== conflicting copy
│ │ └── package.json
│ └── #mui/material-ui <== host copy
├── src
└── package.json
// When installed normally
host-app
├── node_modules
│ ├── #my/custom-components
│ │ ├── dist
│ │ └── package.json
│ └── #mui/material-ui <== only copy
├── src
└── package.json
To fix the problem, I:
Removed the sym link (npm install in the host app)
Manually built #my/custom-components (npm pack)
Replaced host-app/node_modules/#my/custom-components with the built package.
I found a solution, what i did was,
create the theme project with custom build configurations with rollup. at their I added #mui/ as external packages. then export the mui5 theme provider.
then consumes it in the consumer project. consumer project need to have mui5 as dependencies. simple we are sharing the mui5.
sample rollup config ==>
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
const packageJson = require('./package.json'); // eslint-disable-line #typescript-eslint/no-var-requires
export default {
input: 'src/index.ts',
external: [
'react',
'react-dom',
'prop-types',
'#emotion/react',
'#emotion/styled',
'#mui/lab',
'#mui/icons-material',
'#mui/material',
'#mui/material/styles',
'#mui/styles',
],
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true,
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true,
},
],
plugins: [
resolve(),
commonjs(),
typescript({ useTsconfigDeclarationDir: true }),
],
};
I ran into a similar problem with a component built with Vite and MUI 5. In local testing the component didn't pick up the correct theme. It was due to the problem identified by #elstgav with npm link and nod_modules existing in the linked package folder.
I use Vite's alias resolve config (same as Rollup's resolve) to point to the correct node_modules.
vite.config.js:
resolve: {
alias: [
{
find: /^(#mui\/[\w-]+)/,
replacement: path.resolve(__dirname, "node_modules/$1"),
},
],
},
I have found a solution. Adding external theme provider was an overkill that I converted from MUI4.
In MUI 5 only thing that is needed is shared theme file. So place the theme file in the shared component library and import it in the projects that use it, but keep the theme providers local in all three codebases.
Related
Problem statement
When building a Python package I want the build tool to automatically execute the steps to generate the necessary Python files and include them in the package.
Here are some details about the project:
the project repository contains only the hand-written Python and YAML files
to have a fully functional package the YAML files must be compiled into Python scripts
once the Python files are generated from YAMLs, the program needed to compile them is no longer necessary (build dependency).
the hand-written and generated Python files are then packaged together.
The package would then be uploaded to PyPI.
I want to achieve the following:
When the user installs the package from PyPI, all necessary files required for the package to function are included and it is not necessary to perform any compile steps
When the user checks-out the repository and builds the package with python -m build . --wheel, the YAML files are automatically compiled into Python and included in the package. Compiler is required.
When the user checks-out the repository and installs the package from source, the YAML files are automatically compiled into Python and installed. Compiler is required.
(nice to have) When the user checks-out the repository and installs in editable mode, the YAML files are compiled into Python. The user is free to make modifications to both generated and hand-written Python files. Compiler is required.
I have a repository with the following layout:
├── <project>
│ └── <project>
│ ├── __init__.py
│ ├── hand_written.py
│ └── specs
│ └── file.ksc (YAML file)
└── pyproject.toml
And the functional package should look something like this
├── <project>
│ └── <project>
│ ├── __init__.py
│ ├── hand_written.py
│ └── generated
│ └── file.py
├── pyproject.toml
└── <other package metadata>
How can I achieve those goals?
What I have so far
As I am very fresh to Python packaging, I have been struggling to understand the relations between the pyproject.toml, setup.cfg and setup.py and how I can use them to achieve the goals I have outlined above. So far I have a pyproject.toml with the following content:
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "<package>"
version = "xyz"
description = "<description>"
authors = [ <authors> ]
dependencies = [
"kaitaistruct",
]
From reading the setuptools documentation, I understand that there are the build commands, such as:
build_py -- simply copies Python files into the package (no compiling; works differently in editable mode)
build_ext -- builds C/C++ modules (not relevant here?)
I suppose adding the compile steps for the YAML files will involve writing a setup.py file and overwriting a command, but I don't know if this is the right approach, whether it will even work, or if there are better methods, such as using a different build backend.
Alternative approaches
A possible alternative approach would be to manually compile the YAML files prior to starting the installation or build of the package.
I have my native application, which we want to change into flutter. For that, we have decided to build multiple flutter modules and add that to the existing native application. I am not sure whether flutter support building multiple modules in a single native application.
Also in the future, as we want to move away from native completely, I didn't find any solution where we can build a fresh flutter application using already developed flutter modules.
It is possible. What you can do is create modules (packages) somewhere in your project, for example, create a directory modules and place them there.
.
├── modules
│ ├── module1
│ ├── module2
│ ├── module3
│ └── module4
To add them to the current project, in your pubspec.yaml, you can do the following:
dependencies:
# ...
module1:
path: ./modules/module1
# ... etc for other modules
These local modules are called path dependencies.
I have trouble creating a package with setuptools. I have a repository which I'm cleaning up to make it a package. The directory structure looks something like this
my-proj
├── setup.py
├── MANIFEST.in
├── MakeFile
├── README.rst
├── setup.py
└── myproj
├── __init__.py
├── my_code.py
├── templates
│ ├── template1.yaml
│ ├── template2.yaml
Initial version of "my_code.py" had code snippet which would directly reference the files withing templates folder to do some processing. If I package this using setup tools, I provide the following information in these files:
MANIFEST.in:
include README.rst
include requirements.txt
include LICENSE.txt
recursive-include myproj/templates *
setup.py:
setup(
name='myproj',
package_dir={'testbed_init': 'testbed_init'},
package_data={'templates': ['templates/*'], 'configs': ['configs/*']},
include_package_data=True,
)
My question is as follows. In "my_Code.py" I used to reference templates directly without any problem as I would run script from the myproj folder. If I package this, how can I make sure, I include the templates as part of package and when script runs, I need to open the templates relative to where the package is installed.
Code snippet from my_code.py:
if _type == "a":
temp_file = f"templates/template1.yaml"
else:
temp_file = f"templates/template2.yaml"
build_config(deploy_esx_file, output_file, data)
Code snippet of what happens in build_config:
def build_config(template_file, output_file, inputs):
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
template = templateEnv.get_template(template_file)
outputText = template.render(inputs)
with open(output_file, 'w') as h:
h.write(outputText)
I have opened a folder in VS code and I am trying to set it up.
It's a python project and its directory structure is as:
Project
├── common_features
│ ├── ...
├── core
│ ├── features
│ └── main.py
│ └── tests
├── django project
│ ├── django_app1
│ ├── manage.py
│ ├── ...
└── tests
│ ├── ...
└── runner.py
The project runs as a django project from the django_project dir. It uses modules located in common_features and core. Core is designed such that it could also run on its own. You can also run core from runner.py
The problem is that all our module imports are not being resolved but 3rd party packages work well.
unresolved import 'core.config' Python(unresolved-import)
In PyCharm, I have marked Project, core and django_project as "sources root" and it works like a charm. Not sure how to do that in VS code.
I have tried making some changes in launch.json and settings.json but none are working. I am new to VS code so I'm unable to understand what it is that I'm doing wrong.
Thanks.
Can you try adding the following line to your settings.json file?
{
"python.autoComplete.extraPaths": ["./src"]
}
More info about this here: https://github.com/microsoft/python-language-server/blob/master/TROUBLESHOOTING.md#unresolved-import-warnings
I'm starting to learn Ionic2, I have create a new empty project with ionic start myproject blank --v2 and everything works correctly if I do ionic serve.
Then I read this tutorial and many others. All of them state that the ionic folder structure should have an app folder:
If I look at my project folder structure I can't see any app folder. My structure looks so:
.
├── hooks
├── plugins
├── scss
├── www
│ ├── index.html
│ ├── css
│ ├── img
│ ├── js
│ └── lib
├── bower.json
├── config.xml
├── gulpfile.js
├── ionic.project
└── package.json
Now I'd like to follow this tutorial in order to build my first application but as you can see the folder structure of that example is different from mine and as an Ionic beginner I'm a little confused.
FIY (if it matters):
I'm referring to this page for the templates.
cordova -v: 6.2.0
ionic -v: 1.7.15
It might because your Node.js needs update.
First use node --version in your terminal (if you use Mac) to check the version of your Node.js. I had the same problem with you when node version in my Mac was v5.10.1 and solved it by using brew upgrade node to upgrade my Node.js to v6.3.1.
After updating your Node.js to the latest version just use ionic start myProject --v2 to create a new project and then the new project you created should have /app inside.