SZJX
Trying to get Typescript to work with Phoenix 1.4.0 dev
I’m now trying to start a new project with Phoenix 1.4.0 as it comes with Webpack by default, and I’m trying to get Typescript to work with it, which is surprisingly difficult.
I changed the file app.js to app.ts, and the problem I’m struggling with now is the first statement: import css from '../css/app.css';. Apparently, from questions such as https://stackoverflow.com/questions/41336858/how-to-import-css-modules-with-typescript-react-and-webpack, and https://stackoverflow.com/questions/40382842/cant-import-css-scss-modules-typescript-says-cannot-find-module, it’s a nontrivial task to import CSS modules in Typescript… Typescript wouldn’t recognize the module which doesn’t end in .js or .ts.
According to the instructions in that post, I tried to create a file called typings.d.ts:
declare module '*.css' {
interface IClassNames {
[className: string]: string;
}
const classNames: IClassNames;
export = classNames;
}
Now, Typescript doesn’t complain about the module. However, running npx webpack --mode development doesn’t actually emit the CSS file whatsoever. webpack just completely ignores the app.css file.
The following is my webpack.config.js. I only changed two places:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = (env, options) => ({
optimization: {
minimizer: [new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }), new OptimizeCSSAssetsPlugin({})]
},
// entry: './js/app.js',
entry: './js/app.ts',
output: {
filename: 'app.js',
path: path.resolve(__dirname, '../priv/static/js')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader'
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({ filename: '../css/app.css' }),
new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
]
});
I think this should be fairly easy to replicate with a new project.
cd assetsnpm install --save-dev typescript ts-loadernpx tsc init- Create
typings.d.tsin the folder - Edit
webpack.config.js
I think the problem might lie with the Typescript module declaration. Unfortunately I don’t know enough to come up with a more sensible solution. I tried to generate a module for each css file in the /css folder with GitHub - Quramy/typed-css-modules: Creates .d.ts files from CSS Modules .css files · GitHub, but Typescript complains that assets/css/app.css.d.ts' is not a module.
Should I just give up the idea of turning app.js into a Typescript file and try to integrate Typescript in some other fashion, e.g. wrapping it in a module which is to be imported in app.js?
Marked As Solved
SZJX
Sorry, misread your reply in a hurry. I think the contents conform to the guides as well:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true
}
}
It seems that importing CSS modules is inherently thorny with Typescript… The two workarounds that worked:
- Keep
app.jsin Javascript. Then when importing other modules defined in TS, one needs to append the.tssuffix to those modules. - Use Typescript for
app.tsbut write
instead ofdeclare function require(name: string): string; const css = require('../css/app.css');import css from '../css/app.css';at the top ofapp.ts.
Also Liked
peerreynders
FYI: The POI documentation recommends this tsconfig.json:
{
"compilerOptions": {
// this aligns with Vue's browser support
"target": "es5",
// this enables stricter inference for data properties on `this`
"strict": true,
// if using webpack 2+ or rollup, to leverage tree shaking:
"module": "es2015",
"moduleResolution": "node"
}
}
Furthermore in Zero config React + Typescript + CSS Modules + JEST with Poi (2018-02-18):
Let’s get that fixed too and add a
global.d.tsfile with the following line in it:
declare module '*.css';
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








