CSS / SCSS मॉड्यूल आयात नहीं कर सकते। टाइपस्क्रिप्ट कहते हैं, "मॉड्यूल का पता नहीं लगा सकते"


88

मैं एक सीएसएस मॉड्यूल से एक विषय आयात करने की कोशिश कर रहा हूं, लेकिन टाइपस्क्रिप्ट मुझे "मॉड्यूल नहीं ढूंढ सकता है" त्रुटि देता है और थीम रनटाइम पर लागू नहीं होती है। मुझे लगता है कि मेरे वेबपैक कॉन्फ़िगरेशन में कुछ गड़बड़ है लेकिन मुझे यकीन नहीं है कि समस्या कहाँ है।

मैं निम्नलिखित टूल का उपयोग कर रहा हूं:

"typescript": "^2.0.3"
"webpack": "2.1.0-beta.25"
"webpack-dev-server": "^2.1.0-beta.9"
"react": "^15.4.0-rc.4"
"react-toolbox": "^1.2.3"
"node-sass": "^3.10.1"
"style-loader": "^0.13.1"
"css-loader": "^0.25.0"
"sass-loader": "^4.0.2"
"sass-lint": "^1.9.1"
"sasslint-webpack-plugin": "^1.0.4"

मेरा यहाँ है webpack.config.js

var path = require('path');
var webpack = require('webpack');
var sassLintPlugin = require('sasslint-webpack-plugin');

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
    './src/index.tsx',
  ],
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'http://localhost:8080/',
    filename: 'dist/bundle.js',
  },
  devtool: 'source-map',
  resolve: {
    extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'source-map-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loader: 'tslint-loader',
      exclude: /node_modules/,
      enforce: 'pre',
    }, {
      test: /\.tsx?$/,
      loaders: [
        'react-hot-loader/webpack',
        'awesome-typescript-loader',
      ],
      exclude: /node_modules/,
    }, {
      test: /\.scss$/,
      loaders: ['style', 'css', 'sass']
    }, {
      test: /\.css$/,
      loaders: ['style', 'css']
    }],
  },
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  },
  plugins: [
    new sassLintPlugin({
      glob: 'src/**/*.s?(a|c)ss',
      ignoreFiles: ['src/normalize.scss'],
      failOnWarning: false, // Do it.
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    contentBase: './'
  },
};

और मेरा App.tsxजहां मैं आयात करने की कोशिश कर रहा हूं:

import * as React from 'react';

import { AppBar } from 'react-toolbox';
import appBarTheme from 'react-toolbox/components/app_bar/theme.scss'
// local ./theme.scss stylesheets aren't found either 

interface IAppStateProps {
  // No props yet
}

interface IAppDispatchProps {
  // No state yet
}

class App extends React.Component<IAppStateProps & IAppDispatchProps, any> {

  constructor(props: IAppStateProps & IAppDispatchProps) {
    super(props);
  }

  public render() {
    return (

        <div className='wrapper'>
          <AppBar title='My App Bar' theme={appBarTheme}>
          </AppBar>
        </div>

    );
  }
}

export default App;

अन्य प्रकार के स्टाइलशीट मॉड्यूल को आयात करने में सक्षम करने के लिए और क्या आवश्यक है?

जवाबों:


125

टाइपस्क्रिप्ट को पता नहीं है कि इसके अलावा कोई अन्य फ़ाइल है .tsया .tsxनहीं, अगर किसी अज्ञात फ़ाइल के प्रत्यय में कोई त्रुटि है तो यह एक त्रुटि देगा।

यदि आपके पास एक वेबपैक कॉन्फिगरेशन है जो आपको अन्य प्रकार की फाइलें आयात करने की अनुमति देता है, तो आपको टाइपस्क्रिप्ट कंपाइलर को बताना होगा कि ये फाइलें मौजूद हैं। ऐसा करने के लिए एक घोषणापत्र फ़ाइल जोड़ें जिसमें आप फिटिंग नामों के साथ मॉड्यूल घोषित करते हैं।

घोषित करने के लिए मॉड्यूल की सामग्री फ़ाइल प्रकार के लिए उपयोग किए जाने वाले वेबपैक लोडर पर निर्भर करती है। एक वेबपैक विन्यास में जो sass-loadercss-loaderस्टाइल-लोडर के*.scss माध्यम से फाइल को पाइप करता है , आयातित मॉड्यूल में कोई सामग्री नहीं होगी, और सही मॉड्यूल घोषणा इस तरह दिखेगी:

// declaration.d.ts
declare module '*.scss';

यदि लोडर को css- मॉड्यूल के लिए कॉन्फ़िगर किया गया है तो इस तरह से घोषणा को बढ़ाएं:

// declaration.d.ts
declare module '*.scss' {
    const content: Record<string, string>;
    export default content;
}

2
अरे यह मेरे काम नहीं आया, हाल ही में कुछ बदल गया है। stackoverflow.com/questions/56563243/…
Kay

50

यहां एक पूर्ण कॉन्फ़िगरेशन है जो मेरे लिए काम करता है (मैंने इस पर केवल एक घंटे का दर्दनाक परीक्षण और त्रुटि बिताई है - यदि कोई भी समान मुद्दों में चलता है:

टाइपस्क्रिप्ट + वेबपैक + सास

webpack.config.js

module.exports = {
  //mode: "production", 
    mode: "development", devtool: "inline-source-map",

    entry: [ "./src/app.tsx"/*main*/ ], 
    output: {
        filename: "./bundle.js"  // in /dist
    },
    resolve: {
        // Add `.ts` and `.tsx` as a resolvable extension.
        extensions: [".ts", ".tsx", ".js", ".css", ".scss"]
    },
    module: {
        rules: [

            { test: /\.tsx?$/, loader: "ts-loader" }, 

            { test: /\.scss$/, use: [ 
                { loader: "style-loader" },  // to inject the result into the DOM as a style block
                { loader: "css-modules-typescript-loader"},  // to generate a .d.ts module next to the .scss file (also requires a declaration.d.ts with "declare modules '*.scss';" in it to tell TypeScript that "import styles from './styles.scss';" means to load the module "./styles.scss.d.td")
                { loader: "css-loader", options: { modules: true } },  // to convert the resulting CSS to Javascript to be bundled (modules:true to rename CSS classes in output to cryptic identifiers, except if wrapped in a :global(...) pseudo class)
                { loader: "sass-loader" },  // to convert SASS to CSS
                // NOTE: The first build after adding/removing/renaming CSS classes fails, since the newly generated .d.ts typescript module is picked up only later
            ] }, 

        ]
    }
}; 

declarations.d.tsअपने प्रोजेक्ट में भी डालें :

// We need to tell TypeScript that when we write "import styles from './styles.scss' we mean to load a module (to look for a './styles.scss.d.ts'). 
declare module '*.scss'; 

और आपको इन सभी को अपने package.jsonदेव-आश्रितों की आवश्यकता होगी:

  "devDependencies": {
    "@types/node-sass": "^4.11.0",
    "node-sass": "^4.12.0",
    "css-loader": "^1.0.0",
    "css-modules-typescript-loader": "^2.0.1",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "ts-loader": "^5.3.3",
    "typescript": "^3.4.4",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"
  }

फिर आपको mystyle.d.tsअपने द्वारा mystyle.scssपरिभाषित सीएसएस वर्गों से युक्त एक अगला प्राप्त करना चाहिए , जिसे आप एक टाइपस्क्रिप्ट मॉड्यूल के रूप में आयात कर सकते हैं और इस तरह उपयोग कर सकते हैं:

import * as styles from './mystyles.scss'; 

const foo = <div className={styles.myClass}>FOO</div>; 

सीएसएस स्वचालित रूप से लोड हो जाएगा ( styleडोम में एक तत्व के रूप में इंजेक्ट किया जाता है ) और पृष्ठ में अपनी शैलियों को अलग करने के लिए .scss में अपने सीएसएस वर्गों के बजाय गुप्त पहचानकर्ता होते हैं (जब तक आप उपयोग नहीं करते :global(.a-global-class) { ... })।

ध्यान दें कि जब भी आप सीएसएस कक्षाएं जोड़ते हैं या उन्हें हटाते हैं या आयात करते हैं, तो पहला संकलन विफल हो जाएगा , क्योंकि आयातित रहस्यमय शैलियाँ .ts पुराने संस्करण हैं और संकलन के दौरान उत्पन्न नया संस्करण नहीं है। बस फिर से संकलन।

का आनंद लें।


"नोट: सीएसएस वर्गों को जोड़ने / हटाने / नाम बदलने के बाद पहला निर्माण विफल हो जाता है, क्योंकि नव निर्मित .d.ts टाइपस्क्रिप्ट मॉड्यूल केवल बाद में उठाया जाता है" - उस भाग को कैसे हल किया जाए?
जॉन लॉरिडेन

3
@JonLauridsen इसे webpack.config.js में नियमों के सरणी के निचले (अंत) पर ts-loader सेट करके हल किया जा सकता है। तो ts-loader एक सही * .scss.d.ts फ़ाइलों को संकलित करेगा क्योंकि वे पहले उत्पन्न हो जाएंगे।
यान पाक

1
@YanPak धन्यवाद, स्टाइल लोडर के नीचे ts- लोडर को स्थानांतरित करने के साथ global.d.tsमेरी srcनिर्देशिका में ए जोड़ने से यह मेरे लिए तय हो गया।
लक्स

5

यदि आप tsconfig.json पथ सेटिंग का उपयोग कर रहे हैं तो सिर

ध्यान दें कि यदि आप अपने आयात को छोटा करने के लिए tsconfig रास्तों के साथ इन समाधानों का उपयोग कर रहे हैं, तो आपको अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता होगी।

यदि आप इस तरह एक पथ tsconfig का उपयोग करने के लिए होता है:

{
  "compilerOptions": {
    "paths": {
      "style/*": [ "src/style/*" ],
    }
  }
}

तो आप कर सकते हैं:

import { header } from 'style/ui.scss';

फिर आपको अपने वेबपैक पर एक मॉड्यूल समाधान कॉन्फ़िगरेशन को भी जोड़ने की आवश्यकता है जैसे:

module.exports = {
  ...
  resolve: {
    ...
    alias: {
      style: path.resolve(__dirname, 'src', 'style')
    }
  }
}

सुनिश्चित करें कि आपके सेटअप के अनुसार पथ सेट है।

इससे यह पता चलता है कि वेबपैक को पता है कि कहां से देखना है क्योंकि उसे लगता है कि नया आयात पथ वास्तव में एक मॉड्यूल है इसलिए यह नोड_मॉड्यूल्स डायरेक्टरी को डिफॉल्ट करता है। इस कॉन्फ़िगरेशन के साथ, यह जानता है कि इसे कहाँ देखना है और इसे ढूंढना है और निर्माण कार्य करता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.