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 https://github.com/Quramy/typed-css-modules, 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?




















